- The destructor of the static objects will be called in the reverse order of constructors. If other destructors call a function of the log agent after the destructor of the log agent, it could be crashed. Solution is to construct the log agent object early.
- If a process is forked, both processes share all created sockets. Cleaning resources in one process causes undefined behaviours in other process. Solution is to empty the destructor of log agent. Those resources are manually cleaned by the api functions of the log agent. --- src/log/agent/lga_agent.cc | 29 ++++++++++++++++++++--------- src/log/agent/lga_agent.h | 13 ++++--------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/log/agent/lga_agent.cc b/src/log/agent/lga_agent.cc index e84ea3a28..e8d3f01ef 100644 --- a/src/log/agent/lga_agent.cc +++ b/src/log/agent/lga_agent.cc @@ -135,7 +135,22 @@ ScopeData::~ScopeData() { //------------------------------------------------------------------------------ // LogAgent //------------------------------------------------------------------------------ + +// Create the static instance of the log agent early. Sometime the destructor +// of other class calls a function of the log agent. If the log agent was +// cleaned in its destructor, the destructor of other class could be crashed +// while calling a function of the log agent. The destructor of the static +// objects will be called in the reverse order of constructors. Therefore, +// constructing the log agent early will prevent the error in other +// destructors. +LogAgent LogAgent::me; + +LogAgent* LogAgent::instance() { + return &me; +} + LogAgent::LogAgent() { + TRACE_ENTER(); client_list_.clear(); // There is high risk of calling one @LogClient method // in the body of other @LogClient methods, such case would cause deadlock @@ -161,19 +176,15 @@ LogAgent::LogAgent() { m_NCS_SEL_OBJ_CREATE(&log_server_up_sel_); atomic_data_.waiting_log_server_up = true; + TRACE_LEAVE(); } LogAgent::~LogAgent() { TRACE_ENTER(); - ScopeLock scopeLock(mutex_); - - stop_recovery2_thread(); - lga_shutdown(); - m_NCS_SEL_OBJ_DESTROY(&init_clm_status_sel_); - m_NCS_SEL_OBJ_DESTROY(&log_server_up_sel_); - client_list_.clear(); - atomic_data_.waiting_log_server_up = false; - + // Shouldn't clean the shared resources like sockets because it could be + // used in other process. If this process was forked, two processes will + // share all created sockets. Cleaning resources in one process causes + // undefined behaviours in other process. TRACE_LEAVE(); } diff --git a/src/log/agent/lga_agent.h b/src/log/agent/lga_agent.h index 957adc716..1cf0dd49c 100644 --- a/src/log/agent/lga_agent.h +++ b/src/log/agent/lga_agent.h @@ -82,15 +82,7 @@ class LogClient; //< class LogAgent { public: - static std::shared_ptr<LogAgent>& instance() { - // Ensure this static singleton instance is only destroyed when - // no one is using it. Note that: static data can be destroyed - // in log application thread which calls exit() libc. So, introducing - // shared_ptr<> to avoid races among threads. - static std::shared_ptr<LogAgent> me = - std::shared_ptr<LogAgent>{new LogAgent()}; - return me; - } + static LogAgent* instance(); //< // C++ APIs wrapper for corresponding C LOG Agent APIs @@ -292,6 +284,9 @@ class LogAgent { // Log server sync params NCS_SEL_OBJ log_server_up_sel_; + // Static object of this class + static LogAgent me; + DELETE_COPY_AND_MOVE_OPERATORS(LogAgent); }; -- 2.25.1 _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel