Skip to content
Snippets Groups Projects
Commit ab81f3dd authored by Xavier ELATTAOUI's avatar Xavier ELATTAOUI
Browse files

Memory leak in Communication class fixed

parent 9abd9a9d
No related branches found
No related tags found
No related merge requests found
pom.xml 100644 → 100755
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
</parent> </parent>
<groupId>fr.soleil.device</groupId> <groupId>fr.soleil.device</groupId>
<artifactId>ABC1260-${aol}-${mode}</artifactId> <artifactId>ABC1260-${aol}-${mode}</artifactId>
<version>1.3.2-SNAPSHOT</version> <version>1.3.2</version>
<packaging>nar</packaging> <packaging>nar</packaging>
<name>ABC1260</name> <name>ABC1260</name>
<description>ABC1260 device</description> <description>ABC1260 device</description>
...@@ -41,9 +41,9 @@ ...@@ -41,9 +41,9 @@
</dependency> </dependency>
</dependencies> </dependencies>
<scm> <scm>
<connection>${scm.connection.svn.tango-ds}/DeviceClasses/RadioProtection/ABC1260/trunk</connection> <connection>git@gitlab.synchrotron-soleil.fr:software-control-system/tango-devices/radioprotection/abc1260.git</connection>
<developerConnection>${scm.developerConnection.svn.tango-ds}/DeviceClasses/RadioProtection/ABC1260/trunk</developerConnection> <developerConnection>git@gitlab.synchrotron-soleil.fr:software-control-system/tango-devices/radioprotection/abc1260.git</developerConnection>
<url>${scm.url.svn.tango-ds}/DeviceClasses/RadioProtection/ABC1260/trunk</url> <url>https://gitlab.synchrotron-soleil.fr/software-control-system/tango-devices/radioprotection/abc1260</url>
</scm> </scm>
<developers> <developers>
<developer> <developer>
......
...@@ -55,7 +55,7 @@ static const char* RcsId = "$Id: ABC1260.cpp,v 1.23 2013/03/06 08:06:59 xavela E ...@@ -55,7 +55,7 @@ static const char* RcsId = "$Id: ABC1260.cpp,v 1.23 2013/03/06 08:06:59 xavela E
#include <math.h> #include <math.h>
#include <PogoHelper.h> #include <PogoHelper.h>
#include <yat/time/Timer.h> #include <yat/time/Timer.h>
#include <yat4tango/Logging.h> // #include <yat4tango/Logging.h>
#include <yat4tango/DeviceInfo.h> #include <yat4tango/DeviceInfo.h>
/*----- PROTECTED REGION END -----*/ // ABC1260.cpp /*----- PROTECTED REGION END -----*/ // ABC1260.cpp
...@@ -185,7 +185,7 @@ void ABC1260::delete_device() ...@@ -185,7 +185,7 @@ void ABC1260::delete_device()
DELETE_DEVSTRING_ATTRIBUTE(attr_SerialNumber_read); DELETE_DEVSTRING_ATTRIBUTE(attr_SerialNumber_read);
yat4tango::DeviceInfo::release(this); yat4tango::DeviceInfo::release(this);
yat4tango::Logging::release(this); // yat4tango::Logging::release(this);
/*----- PROTECTED REGION END -----*/ // ABC1260::delete_device /*----- PROTECTED REGION END -----*/ // ABC1260::delete_device
} }
...@@ -219,7 +219,7 @@ void ABC1260::init_device() ...@@ -219,7 +219,7 @@ void ABC1260::init_device()
try try
{ {
yat4tango::DeviceInfo::initialize( this, YAT_XSTR(PROJECT_NAME), YAT_XSTR(PROJECT_VERSION) ); yat4tango::DeviceInfo::initialize( this, YAT_XSTR(PROJECT_NAME), YAT_XSTR(PROJECT_VERSION) );
yat4tango::Logging::initialize(this); // yat4tango::Logging::initialize(this);
CREATE_SCALAR_ATTRIBUTE(attr_TotalDose_read); CREATE_SCALAR_ATTRIBUTE(attr_TotalDose_read);
CREATE_SCALAR_ATTRIBUTE(attr_TotalCounts_read); CREATE_SCALAR_ATTRIBUTE(attr_TotalCounts_read);
...@@ -298,7 +298,7 @@ void ABC1260::get_device_property() ...@@ -298,7 +298,7 @@ void ABC1260::get_device_property()
//- Default relay name (none) //- Default relay name (none)
this->inhibitRelayName = "None"; this->inhibitRelayName = "None";
this->isABC1260Model = true; this->isABC1260Model = true;
communicationProtocole = ""; communicationProtocole = "SERIAL";
//- populate with description and possibles values //- populate with description and possibles values
disableAlarmsList.clear(); disableAlarmsList.clear();
disableAlarmsList.push_back("#DESC : Remove # caracter to change device state when one of these alamrs is raised"); disableAlarmsList.push_back("#DESC : Remove # caracter to change device state when one of these alamrs is raised");
......
...@@ -1242,7 +1242,7 @@ void ABC1260Task::init_communication() ...@@ -1242,7 +1242,7 @@ void ABC1260Task::init_communication()
{ {
//- Creates the Proxy //- Creates the Proxy
m_com_p = new Communication(m_host_device, m_proxyDeviceName, m_protocole); m_com_p = new Communication(m_host_device, m_proxyDeviceName, m_protocole);
m_com_p->go(); m_com_p->create_proxy();
} }
} }
catch(std::bad_alloc& bd) catch(std::bad_alloc& bd)
...@@ -1273,7 +1273,7 @@ void ABC1260Task::close_communication() ...@@ -1273,7 +1273,7 @@ void ABC1260Task::close_communication()
{ {
if ( m_com_p ) if ( m_com_p )
{ {
m_com_p->exit(); delete m_com_p;
m_com_p = 0; m_com_p = 0;
} }
} }
......
...@@ -13,11 +13,6 @@ ...@@ -13,11 +13,6 @@
#include <yat/threading/Utilities.h> //- sleep #include <yat/threading/Utilities.h> //- sleep
#include "Communication.hpp" #include "Communication.hpp"
// ----------------------------------------------------------------------------
//- the YAT user messages
const std::size_t WRITE_READ = yat::FIRST_USER_MSG + 1;
const std::size_t READ_ONLY = yat::FIRST_USER_MSG + 2;
const std::size_t CLEAR_ERROR= yat::FIRST_USER_MSG + 10;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
const std::size_t TIME_TO_WAIT_MSG_HANDLED = 2000; //- in ms const std::size_t TIME_TO_WAIT_MSG_HANDLED = 2000; //- in ms
const long TIME_TO_SLEEP_IN_SECONDS = 0; //- in second! const long TIME_TO_SLEEP_IN_SECONDS = 0; //- in second!
...@@ -40,13 +35,12 @@ namespace ABC1260_ns ...@@ -40,13 +35,12 @@ namespace ABC1260_ns
Communication::Communication (Tango::DeviceImpl * host_device, Communication::Communication (Tango::DeviceImpl * host_device,
std::string comDevName, std::string comDevName,
std::string protocole) std::string protocole)
: yat4tango::DeviceTask(host_device), : yat4tango::TangoLogAdapter(host_device),
m_com_protocole(NOT_DEFINED), m_com_protocole(NOT_DEFINED),
m_protocole(protocole), m_protocole(protocole),
m_dsproxy (0), m_dsproxy (0),
m_host_dev(host_device), m_host_dev(host_device),
m_dev_name(comDevName), m_dev_name(comDevName),
m_response(""),
m_error(""), m_error(""),
m_com_state(Tango::INIT) m_com_state(Tango::INIT)
{ {
...@@ -90,7 +84,6 @@ void Communication::create_proxy() ...@@ -90,7 +84,6 @@ void Communication::create_proxy()
} }
catch(Tango::DevFailed& df) catch(Tango::DevFailed& df)
{ {
yat::AutoMutex<> guard(m_error_mutex);
m_com_state = Tango::FAULT; m_com_state = Tango::FAULT;
m_error = "Failed to create proxy on \"" + m_dev_name + "\" : \n"; m_error = "Failed to create proxy on \"" + m_dev_name + "\" : \n";
m_error+= std::string(df.errors[0].desc); m_error+= std::string(df.errors[0].desc);
...@@ -127,7 +120,6 @@ void Communication::check_proxy() ...@@ -127,7 +120,6 @@ void Communication::check_proxy()
} }
catch(Tango::DevFailed& df) catch(Tango::DevFailed& df)
{ {
yat::AutoMutex<> guard(m_error_mutex);
m_com_state = Tango::ALARM; m_com_state = Tango::ALARM;
//- store the Tango error //- store the Tango error
m_error = std::string(df.errors[0].desc); m_error = std::string(df.errors[0].desc);
...@@ -146,14 +138,12 @@ void Communication::check_proxy() ...@@ -146,14 +138,12 @@ void Communication::check_proxy()
m_com_state = m_dsproxy->get_device_proxy()->state(); m_com_state = m_dsproxy->get_device_proxy()->state();
if( m_com_state != Tango::OPEN ) if( m_com_state != Tango::OPEN )
{ {
yat::AutoMutex<> guard(m_error_mutex);
m_com_state = Tango::ALARM; m_com_state = Tango::ALARM;
m_error = "Cannot read back state of device \"" + m_dev_name + "\" or its Tango state is not OPEN.\n"; m_error = "Cannot read back state of device \"" + m_dev_name + "\" or its Tango state is not OPEN.\n";
} }
} }
catch(Tango::DevFailed& df) catch(Tango::DevFailed& df)
{ {
yat::AutoMutex<> guard(m_error_mutex);
m_com_state = Tango::ALARM; m_com_state = Tango::ALARM;
m_error = "Cannot read back state of device \"" + m_dev_name + "\" \n"; m_error = "Cannot read back state of device \"" + m_dev_name + "\" \n";
m_error+= std::string(df.errors[0].desc); m_error+= std::string(df.errors[0].desc);
...@@ -163,66 +153,33 @@ void Communication::check_proxy() ...@@ -163,66 +153,33 @@ void Communication::check_proxy()
} }
} }
//----------------------------------------------- // ============================================================================
//- the user core of the Task ------------------- // Communication::write_read
void Communication::process_message (yat::Message& _msg) throw (Tango::DevFailed) // ============================================================================
{ std::string Communication::write_read(const std::string& cmd)
DEBUG_STREAM << "Communication::process_message::receiving msg " << _msg.to_string() << std::endl;
//- handle msg
switch (_msg.type())
{
//- THREAD_INIT =======================
case yat::TASK_INIT:
{
DEBUG_STREAM << "Communication::process_message::THREAD_INIT::thread is starting up" << std::endl;
//- "initialization" code goes here
try
{ {
yat::Timer t; static std::string empty("");
//- configure task std::string response("");
enable_timeout_msg (false);
enable_periodic_msg(false); //- no periodic
create_proxy();
INFO_STREAM << "\t\t Communication::process_message handling TASK_INIT Communication initialized. " << std::endl; if ( !m_dsproxy )
}
catch (std::bad_alloc&)
{ {
ERROR_STREAM << "Communication::process_message OUT_OF_MEMORY cannot allocate device proxy " << std::endl;
//- delete proxy
delete_proxy();
throw;
}
catch(...)
{ {
ERROR_STREAM << "Communication::process_message exception ... caught trying to initialize Communication." << std::endl; m_com_state = Tango::FAULT;
//- delete proxy m_error = "Communication link proxy is not created.";
delete_proxy();
throw;
} }
Tango::Except::throw_exception("COMMUNICATION_ERROR",
m_error,
"Communication::write_read");
} }
break;
//- TASK_EXIT ======================= try
case yat::TASK_EXIT:
{ {
//- noop check_proxy();
INFO_STREAM << "Communication::process_message handling TASK_EXIT thread is quitting ..." << std::endl;
} }
break; catch(...)
//- TASK_PERIODIC ===================
case yat::TASK_PERIODIC:
{ {
//- code relative to the task's periodic job goes here return empty;
} }
break;
//- USER_DEFINED_MSG ================
case WRITE_READ:
{
std::string cmd = _msg.get_data<std::string>();
//- erase last command response
m_response.clear();
try try
{ {
...@@ -230,90 +187,47 @@ void Communication::process_message (yat::Message& _msg) throw (Tango::DevFailed ...@@ -230,90 +187,47 @@ void Communication::process_message (yat::Message& _msg) throw (Tango::DevFailed
{ {
DEBUG_STREAM << "Communication::WRITE_READ -> for cmd *" << cmd << "*" << std::endl; DEBUG_STREAM << "Communication::WRITE_READ -> for cmd *" << cmd << "*" << std::endl;
m_response.clear(); response.clear();
//- send the cmd //- send the cmd
m_dsproxy->command_in(m_write_cmd, cmd); m_dsproxy->command_in(m_write_cmd, cmd);
//- sleep to let RS adapter to switch mode //- sleep to let RS adapter to switch mode
yat::ThreadingUtilities::sleep(TIME_TO_SLEEP_IN_SECONDS, TIME_TO_SLEEP_IN_NANOSECONDS); yat::ThreadingUtilities::sleep(TIME_TO_SLEEP_IN_SECONDS, TIME_TO_SLEEP_IN_NANOSECONDS);
//- and read back its response //- and read back its response
m_dsproxy->command_out(m_read_cmd, m_response); m_dsproxy->command_out(m_read_cmd, response);
//- sleep to let RS adapter to switch mode //- sleep to let RS adapter to switch mode
yat::ThreadingUtilities::sleep(TIME_TO_SLEEP_IN_SECONDS, SLEEP_AFTER_READ_IN_NANOSECONDS); yat::ThreadingUtilities::sleep(TIME_TO_SLEEP_IN_SECONDS, SLEEP_AFTER_READ_IN_NANOSECONDS);
DEBUG_STREAM << "Communication::WRITE_READ -> resp *" << m_response << "*" << std::endl; DEBUG_STREAM << "Communication::WRITE_READ -> resp *" << response << "*" << std::endl;
} }
} }
catch(Tango::DevFailed & df) catch(Tango::DevFailed & df)
{ {
yat::AutoMutex<> guard(m_error_mutex);
m_com_state = Tango::ALARM; m_com_state = Tango::ALARM;
m_error = "Communication::write_read received a DevFailed exception : cmd $" + cmd + "$ with resp $" + m_response + "\n"; m_error = "Communication::write_read received a DevFailed exception : cmd $" + cmd + "$ with resp $" + response + "\n";
m_error+= std::string(df.errors[0].desc); m_error+= std::string(df.errors[0].desc);
ERROR_STREAM << m_error << std::endl; ERROR_STREAM << m_error << std::endl;
} }
catch(...) catch(...)
{ {
yat::AutoMutex<> guard(m_error_mutex);
m_com_state = Tango::ALARM; m_com_state = Tango::ALARM;
m_error = "Communication::write_read received a [...] exception.\n"; m_error = "Communication::write_read received a [...] exception.\n";
ERROR_STREAM << m_error << std::endl; ERROR_STREAM << m_error << std::endl;
} }
}
break;
case READ_ONLY:
{
std::string cmd_to_send("");
//- erase last command response
m_response.clear();
try return response;
{
if ( m_dsproxy )
{
m_dsproxy->command_out(m_read_only_cmd, m_response);
DEBUG_STREAM << "Communication::READ O -> resp *" << m_response << "*" << std::endl;
}
}
catch(Tango::DevFailed & df)
{
yat::AutoMutex<> guard(m_error_mutex);
m_com_state = Tango::ALARM;
m_error = "Communication::read received a DevFailed exception : resp [" + m_response + "]\n";
m_error+= std::string(df.errors[0].desc);
ERROR_STREAM << m_error << std::endl;
}
catch(...)
{
yat::AutoMutex<> guard(m_error_mutex);
m_com_state = Tango::ALARM;
m_error = "Communication::write_read received a [...] exception.\n";
ERROR_STREAM << m_error << std::endl;
}
} }
break;
case CLEAR_ERROR:
{
DEBUG_STREAM << "Communication::process_message entering handling of CLEAR_ERROR msg" << std::endl;
yat::AutoMutex<> guard(m_error_mutex);
m_com_state = Tango::ON;
m_error.clear();
}
break;
} //- switch (_msg.type())
} //- Communication::process_message
// ============================================================================ // ============================================================================
// Communication::write_read // Communication::read
// ============================================================================ // ============================================================================
std::string Communication::write_read(const std::string& cmd) std::string Communication::read()
{ {
bool wait = true;
static std::string empty(""); static std::string empty("");
std::string response("");
if ( !m_dsproxy ) if ( !m_dsproxy )
{ {
{ {
yat::AutoMutex<> guard(m_error_mutex);
m_com_state = Tango::FAULT; m_com_state = Tango::FAULT;
m_error = "Communication link proxy is not created."; m_error = "Communication link proxy is not created.";
} }
...@@ -331,54 +245,29 @@ std::string Communication::write_read(const std::string& cmd) ...@@ -331,54 +245,29 @@ std::string Communication::write_read(const std::string& cmd)
return empty; return empty;
} }
//- prepare msg try
yat::Message * msg = new yat::Message(WRITE_READ, MAX_USER_PRIORITY, wait);
//- attach the command to send
msg->attach_data(cmd);
//- wait msg to get back response
wait_msg_handled(msg->duplicate(), TIME_TO_WAIT_MSG_HANDLED);
return m_response;
}
// ============================================================================
// Communication::read
// ============================================================================
std::string Communication::read()
{
bool wait = true;
static std::string empty("");
if ( !m_dsproxy )
{ {
if ( m_dsproxy )
{ {
yat::AutoMutex<> guard(m_error_mutex); m_dsproxy->command_out(m_read_only_cmd, response);
m_com_state = Tango::FAULT; DEBUG_STREAM << "Communication::READ O -> resp *" << response << "*" << std::endl;
m_error = "Communication link proxy is not created.";
} }
Tango::Except::throw_exception("COMMUNICATION_ERROR",
m_error,
"Communication::write_read");
} }
catch(Tango::DevFailed & df)
try
{ {
check_proxy(); m_com_state = Tango::ALARM;
m_error = "Communication::read received a DevFailed exception : resp [" + response + "]\n";
m_error+= std::string(df.errors[0].desc);
ERROR_STREAM << m_error << std::endl;
} }
catch(...) catch(...)
{ {
return empty; m_com_state = Tango::ALARM;
m_error = "Communication::write_read received a [...] exception.\n";
ERROR_STREAM << m_error << std::endl;
} }
//- prepare msg return response;
yat::Message * msg = new yat::Message(READ_ONLY, MAX_USER_PRIORITY, wait);
//- wait msg to get back response
wait_msg_handled(msg->duplicate(), TIME_TO_WAIT_MSG_HANDLED);
return m_response;
} }
// ============================================================================ // ============================================================================
...@@ -386,20 +275,8 @@ std::string Communication::read() ...@@ -386,20 +275,8 @@ std::string Communication::read()
// ============================================================================ // ============================================================================
void Communication::clear_error() void Communication::clear_error()
{ {
bool wait = true; m_com_state = Tango::ON;
m_error.clear();
if ( !m_dsproxy )
{
Tango::Except::throw_exception("COMMUNICATION_ERROR",
"Communication link proxy is not created.",
"Communication::clear_error");
}
//- prepare msg
yat::Message * msg = new yat::Message(CLEAR_ERROR, MAX_USER_PRIORITY, wait);
//- wait
wait_msg_handled(msg, TIME_TO_WAIT_MSG_HANDLED);
} }
} //- end namespace } //- end namespace
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <tango.h> #include <tango.h>
#include <string> #include <string>
#include <DeviceProxyHelper.h> #include <DeviceProxyHelper.h>
#include <yat4tango/DeviceTask.h> #include <yat4tango/LogHelper.h>
/** /**
* \brief Class to manage communication link * \brief Class to manage communication link
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
namespace ABC1260_ns namespace ABC1260_ns
{ {
class Communication : public yat4tango::DeviceTask class Communication : yat4tango::TangoLogAdapter
{ {
public : public :
typedef enum { typedef enum {
...@@ -55,6 +55,11 @@ public : ...@@ -55,6 +55,11 @@ public :
std::string read(); std::string read();
/**
* \brief Proxy creation.
*/
void create_proxy();
/** /**
* \brief Checks proxy creation. * \brief Checks proxy creation.
*/ */
...@@ -66,12 +71,10 @@ public : ...@@ -66,12 +71,10 @@ public :
* \brief Returns communication errors if any. * \brief Returns communication errors if any.
*/ */
std::string get_com_error() { std::string get_com_error() {
yat::AutoMutex<> guard(m_error_mutex);
return m_error; return m_error;
} }
Tango::DevState get_com_state() { Tango::DevState get_com_state() {
yat::AutoMutex<> guard(m_error_mutex);
return m_com_state; return m_com_state;
} }
...@@ -82,16 +85,9 @@ public : ...@@ -82,16 +85,9 @@ public :
protected : protected :
//- mutex
yat::Mutex m_error_mutex;
void process_message (yat::Message& _msg)
throw (Tango::DevFailed);
private : private :
void create_proxy();
void delete_proxy(); void delete_proxy();
void check_proxy(); void check_proxy();
...@@ -109,16 +105,13 @@ private : ...@@ -109,16 +105,13 @@ private :
//- communication device name //- communication device name
std::string m_dev_name; std::string m_dev_name;
//- controller response
std::string m_response;
//- errors //- errors
std::string m_error; std::string m_error;
//- communication state //- communication state
Tango::DevState m_com_state; Tango::DevState m_com_state;
//- Write/Read commands //- Write/Read commands names
std::string m_write_cmd; std::string m_write_cmd;
std::string m_read_cmd; std::string m_read_cmd;
std::string m_read_only_cmd; std::string m_read_only_cmd;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment