diff options
author | dhinton <dhinton@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2002-05-23 18:09:54 +0000 |
---|---|---|
committer | dhinton <dhinton@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2002-05-23 18:09:54 +0000 |
commit | adbbcb5245b1aad5a91c77af56473d694518e6b0 (patch) | |
tree | c2c80b11e4d29995f44d6630fe5e2a505ec84d80 | |
parent | 0372b477f08e3d7649b4610b492ec6509a8b92a2 (diff) | |
download | ATCD-adbbcb5245b1aad5a91c77af56473d694518e6b0.tar.gz |
ChangeLogTag:Thu May 23 17:39:02 UTC 2002 Don Hinton <dhinton@ieee.org>
-rw-r--r-- | ChangeLog | 49 | ||||
-rw-r--r-- | ChangeLogs/ChangeLog-02a | 49 | ||||
-rw-r--r-- | ChangeLogs/ChangeLog-03a | 49 | ||||
-rw-r--r-- | ace/DLL.cpp | 199 | ||||
-rw-r--r-- | ace/DLL.h | 28 | ||||
-rw-r--r-- | ace/Framework_Component.cpp | 35 | ||||
-rw-r--r-- | ace/Framework_Component.h | 9 | ||||
-rw-r--r-- | ace/Makefile | 1 | ||||
-rw-r--r-- | ace/Object_Manager.cpp | 10 | ||||
-rw-r--r-- | ace/Parse_Node.cpp | 2 | ||||
-rw-r--r-- | ace/Parse_Node.h | 2 | ||||
-rw-r--r-- | ace/Service_Config.cpp | 5 | ||||
-rw-r--r-- | ace/Service_Object.cpp | 3 | ||||
-rw-r--r-- | tests/Framework_Component_DLL.cpp | 20 | ||||
-rw-r--r-- | tests/Framework_Component_DLL.h | 17 | ||||
-rw-r--r-- | tests/Framework_Component_Test.cpp | 26 |
16 files changed, 302 insertions, 202 deletions
diff --git a/ChangeLog b/ChangeLog index 9ab1079a9be..478f36722ea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,52 @@ +Thu May 23 17:39:02 UTC 2002 Don Hinton <dhinton@ieee.org> + + * tests/Framework_Component_Test.cpp: + + Removed singleton calls, since they didn't belong there. + + * tests/Framework_Component_DLL.{h,cpp}: + + Moved the Simple_Service method definitions to cpp. + + * ace/Service_Object.cpp: Removed temporary tracing definition. + + * ace/Service_Config.cpp: + * ace/Object_Manager.cpp: + + Removed the ACE_Framework_Repository calls from ACE_Service_Config, + and made ACE_Object_Manager always responsible for cleanup and moved + the call to close_singleton() to after ACE_Service_Repository cleanup + since it is responsible for actually destroying singletons and + unloading dlls that might still be used during ACE_Service_Repository + cleanup. + + * ace/Framework_Component.{h,cpp}: + + added shutting_down_ flag to help avoid self deadlocking on + shutdown. Cleaned up problems in cleanup code. + + * ace/Parse_Node.{h,cpp}: + + Removed ACE_Location_Node::handle() method since it isn't, + and can't be, used anymore. + + * ace/DLL.{h,cpp}: + + Removed all functionality and defered all calls to the new + ACE_DLL_Manager and ACE_DLL_Handle classes below. Also + removed the get/set_handle() methods since no longer make + sense--this may require creating a new class, ACE_DLL_Ex, + and restoring the orginal ACE_DLL, but we'll try to get + away with this way if possible. + + * ace/DLL_Manager.{h,cpp}: + * ace/Makefile: + + Added new ACE_DLL_Handle and ACE_DLL_Manager classes (as + well as the new files). ACE_DLL_Handle basically includes + most of the code and functionality of ACE_DLL, but is refcounted + and managed by ACE_DLL_Manager. And added files to Makefile. + Mon May 20 09:39:32 UTC 2002 Don Hinton <dhinton@ieee.org> * ace/Service_Object.{h,cpp}: diff --git a/ChangeLogs/ChangeLog-02a b/ChangeLogs/ChangeLog-02a index 9ab1079a9be..478f36722ea 100644 --- a/ChangeLogs/ChangeLog-02a +++ b/ChangeLogs/ChangeLog-02a @@ -1,3 +1,52 @@ +Thu May 23 17:39:02 UTC 2002 Don Hinton <dhinton@ieee.org> + + * tests/Framework_Component_Test.cpp: + + Removed singleton calls, since they didn't belong there. + + * tests/Framework_Component_DLL.{h,cpp}: + + Moved the Simple_Service method definitions to cpp. + + * ace/Service_Object.cpp: Removed temporary tracing definition. + + * ace/Service_Config.cpp: + * ace/Object_Manager.cpp: + + Removed the ACE_Framework_Repository calls from ACE_Service_Config, + and made ACE_Object_Manager always responsible for cleanup and moved + the call to close_singleton() to after ACE_Service_Repository cleanup + since it is responsible for actually destroying singletons and + unloading dlls that might still be used during ACE_Service_Repository + cleanup. + + * ace/Framework_Component.{h,cpp}: + + added shutting_down_ flag to help avoid self deadlocking on + shutdown. Cleaned up problems in cleanup code. + + * ace/Parse_Node.{h,cpp}: + + Removed ACE_Location_Node::handle() method since it isn't, + and can't be, used anymore. + + * ace/DLL.{h,cpp}: + + Removed all functionality and defered all calls to the new + ACE_DLL_Manager and ACE_DLL_Handle classes below. Also + removed the get/set_handle() methods since no longer make + sense--this may require creating a new class, ACE_DLL_Ex, + and restoring the orginal ACE_DLL, but we'll try to get + away with this way if possible. + + * ace/DLL_Manager.{h,cpp}: + * ace/Makefile: + + Added new ACE_DLL_Handle and ACE_DLL_Manager classes (as + well as the new files). ACE_DLL_Handle basically includes + most of the code and functionality of ACE_DLL, but is refcounted + and managed by ACE_DLL_Manager. And added files to Makefile. + Mon May 20 09:39:32 UTC 2002 Don Hinton <dhinton@ieee.org> * ace/Service_Object.{h,cpp}: diff --git a/ChangeLogs/ChangeLog-03a b/ChangeLogs/ChangeLog-03a index 9ab1079a9be..478f36722ea 100644 --- a/ChangeLogs/ChangeLog-03a +++ b/ChangeLogs/ChangeLog-03a @@ -1,3 +1,52 @@ +Thu May 23 17:39:02 UTC 2002 Don Hinton <dhinton@ieee.org> + + * tests/Framework_Component_Test.cpp: + + Removed singleton calls, since they didn't belong there. + + * tests/Framework_Component_DLL.{h,cpp}: + + Moved the Simple_Service method definitions to cpp. + + * ace/Service_Object.cpp: Removed temporary tracing definition. + + * ace/Service_Config.cpp: + * ace/Object_Manager.cpp: + + Removed the ACE_Framework_Repository calls from ACE_Service_Config, + and made ACE_Object_Manager always responsible for cleanup and moved + the call to close_singleton() to after ACE_Service_Repository cleanup + since it is responsible for actually destroying singletons and + unloading dlls that might still be used during ACE_Service_Repository + cleanup. + + * ace/Framework_Component.{h,cpp}: + + added shutting_down_ flag to help avoid self deadlocking on + shutdown. Cleaned up problems in cleanup code. + + * ace/Parse_Node.{h,cpp}: + + Removed ACE_Location_Node::handle() method since it isn't, + and can't be, used anymore. + + * ace/DLL.{h,cpp}: + + Removed all functionality and defered all calls to the new + ACE_DLL_Manager and ACE_DLL_Handle classes below. Also + removed the get/set_handle() methods since no longer make + sense--this may require creating a new class, ACE_DLL_Ex, + and restoring the orginal ACE_DLL, but we'll try to get + away with this way if possible. + + * ace/DLL_Manager.{h,cpp}: + * ace/Makefile: + + Added new ACE_DLL_Handle and ACE_DLL_Manager classes (as + well as the new files). ACE_DLL_Handle basically includes + most of the code and functionality of ACE_DLL, but is refcounted + and managed by ACE_DLL_Manager. And added files to Makefile. + Mon May 20 09:39:32 UTC 2002 Don Hinton <dhinton@ieee.org> * ace/Service_Object.{h,cpp}: diff --git a/ace/DLL.cpp b/ace/DLL.cpp index fdab8873b31..ed626b48e9e 100644 --- a/ace/DLL.cpp +++ b/ace/DLL.cpp @@ -5,24 +5,19 @@ #include "ace/Log_Msg.h" #include "ace/ACE.h" -#include "ace/Framework_Component.h" +#include "ace/DLL_Manager.h" ACE_RCSID(ace, DLL, "$Id$") -#undef ACE_TRACE -#define ACE_TRACE(X) ACE_TRACE_IMPL(X) - // Default constructor. Also, by default, the object will be closed // before it is destroyed. -sig_atomic_t ACE_DLL::open_called_ = 0; - ACE_DLL::ACE_DLL (int close_on_destruction) - : handle_ (ACE_SHLIB_INVALID_HANDLE), - open_mode_ (0), + : open_mode_ (0), dll_name_ (0), close_on_destruction_ (close_on_destruction), - last_error_ (0) + dll_handle_ (0), + error_ (0) { ACE_TRACE ("ACE_DLL::ACE_DLL (int)"); } @@ -30,25 +25,18 @@ ACE_DLL::ACE_DLL (int close_on_destruction) ACE_DLL::ACE_DLL (const ACE_DLL &rhs) { ACE_TRACE ("ACE_DLL::ACE_DLL (const ACE_DLL &)"); + // Have to do this since open() calls close()... - this->handle_ = ACE_SHLIB_INVALID_HANDLE; + this->dll_handle_ = 0; this->dll_name_ = 0; - this->last_error_ = 0; + this->close_on_destruction_ = 1; + this->error_ = 0; - if (rhs.handle_ != ACE_SHLIB_INVALID_HANDLE) - { - // Since we call ACE_OS::dlopen(), we always assume the responsibility - // of calling ACE_OS::dlclose() - this->open (rhs.dll_name_, rhs.open_mode_, 1); - } - else - { - // Make copy without calling open. - this->open_mode_ = rhs.open_mode_; - this->dll_name_ = ACE::strnew (rhs.dll_name_); - this->close_on_destruction_ = 1; - this->last_error_ = ACE::strnew (rhs.last_error_); - } + // This will automatically up the refcount. + if (this->open (rhs.dll_name_, rhs.open_mode_, this->close_on_destruction_) != 0) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%s\n"), + this->error ())); } // If the library name and the opening mode are specified than on @@ -57,15 +45,15 @@ ACE_DLL::ACE_DLL (const ACE_DLL &rhs) ACE_DLL::ACE_DLL (const ACE_TCHAR *dll_name, int open_mode, int close_on_destruction) - : handle_ (ACE_SHLIB_INVALID_HANDLE), - open_mode_ (open_mode), + : open_mode_ (open_mode), dll_name_ (0), close_on_destruction_ (close_on_destruction), - last_error_ (0) + dll_handle_ (0), + error_ (0) { ACE_TRACE ("ACE_DLL::ACE_DLL"); - if (this->open (dll_name, open_mode, close_on_destruction) != 0) + if (this->open (dll_name, this->open_mode_, close_on_destruction) != 0) ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("%s\n"), this->error ())); @@ -82,7 +70,6 @@ ACE_DLL::~ACE_DLL (void) this->close (); ACE::strdelete (this->dll_name_); - ACE::strdelete (this->last_error_); } // This method opens the library based on the mode specified using the @@ -102,61 +89,36 @@ ACE_DLL::open (const ACE_TCHAR *dll_filename, int close_on_destruction) { ACE_TRACE ("ACE_DLL::open"); + + this->error_ = 0; - // Recored that open has been called, use by error(). - this->open_called_ = 1; + if (!dll_filename) + return -1; - // This check is necessary as the library could be opened more than - // once without closing it which would cause handle memory leaks. - this->close (); - - // Save name of dll. Note, this must come after close... - ACE::strdelete (this->dll_name_); - this->dll_name_ = ACE::strnew (dll_filename); - - // Reset the flags - this->open_mode_ = open_mode; - this->close_on_destruction_ = close_on_destruction; - - // Find out where the library is - ACE_TCHAR dll_pathname[MAXPATHLEN + 1]; - - // Transform the pathname into the appropriate dynamic link library - // by searching the ACE_LD_SEARCH_PATH. - ACE_Lib_Find::ldfind (dll_filename, - dll_pathname, - (sizeof dll_pathname / sizeof (ACE_TCHAR))); - - // The ACE_SHLIB_HANDLE object is obtained. - this->handle_ = ACE_OS::dlopen (dll_pathname, - open_mode_); - -#if defined (AIX) - if (this->handle_ == ACE_SHLIB_INVALID_HANDLE) + if (this->dll_handle_) { - // AIX often puts the shared library file (most often named shr.o) - // inside an archive library. If this is an archive library - // name, then try appending [shr.o] and retry. - if (0 != ACE_OS_String::strstr (dll_pathname, ACE_LIB_TEXT (".a"))) + // If we have a good handle and its the same name, just return. + if (ACE_OS_String::strcmp (this->dll_name_, dll_filename) == 0) + return 0; + else { - ACE_OS_String::strcat (dll_pathname, ACE_LIB_TEXT ("(shr.o)")); - open_mode |= RTLD_MEMBER; - this->handle_ = ACE_OS::dlopen (dll_pathname, open_mode); + // We already have a dll open, but the caller wants to open another one. + // So close the first one and open the second. + ACE_DLL_Manager::instance()->close_dll (this->dll_name_); } - } -#endif /* AIX */ - - // Always set last error. - this->save_last_error(); - - if (this->handle_ == ACE_SHLIB_INVALID_HANDLE) - { - ACE_ERROR_RETURN ((LM_ERROR, - ACE_LIB_TEXT ("%s\n"), this->error ()), - -1); } + delete this->dll_name_; + this->dll_name_ = ACE::strnew (dll_filename); + this->open_mode_ = open_mode; + this->close_on_destruction_ = close_on_destruction; + + this->dll_handle_ = ACE_DLL_Manager::instance()->open_dll (this->dll_name_, + this->open_mode_); - return 0; + if (!this->dll_handle_) + this->error_ = 1; + + return this->error_ ? -1 : 0; } // The symbol refernce of the name specified is obtained. @@ -165,10 +127,13 @@ void * ACE_DLL::symbol (const ACE_TCHAR *sym_name) { ACE_TRACE ("ACE_DLL::symbol"); - void *sym = ACE_OS::dlsym (this->handle_, sym_name); - // Always set last error. - this->save_last_error (); + this->error_ = 0; + + void *sym = this->dll_handle_->symbol (sym_name); + + if (!sym) + this->error_ = 1; return sym; } @@ -182,85 +147,57 @@ ACE_DLL::close (void) ACE_TRACE ("ACE_DLL::close"); int retval = 0; + if ((retval = ACE_DLL_Manager::instance ()->close_dll (this->dll_name_)) != 0) + this->error_ = 1; - // The handle is checked to see whether the library is closed - // already and the <close_on_destruction_> flag is specified. If - // not, it is closed and the handle is made invalid to indicate that - // it's now closed. - if (this->close_on_destruction_ != 0 && - this->handle_ != ACE_SHLIB_INVALID_HANDLE) - { - ACE_TRACE ("ACE_DLL::close(): close_on_destruction"); - // First remove any associated Framework Components. - ACE_Framework_Repository::instance () ->remove_dll_components (this->dll_name_); - - retval = ACE_OS::dlclose (this->handle_); - - // Always set last error. - this->save_last_error (); - } - - this->handle_ = ACE_SHLIB_INVALID_HANDLE; return retval; } -// This method is used to save the last error of a library operation. - -void -ACE_DLL::save_last_error (void) -{ - ACE_TRACE ("ACE_DLL::save_last_error"); - if (this->open_called_) - { - ACE::strdelete (this->last_error_); - this->last_error_ = ACE::strnew (ACE_OS::dlerror ()); - } -} - // This method is used return the last error of a library operation. ACE_TCHAR * ACE_DLL::error (void) const { ACE_TRACE ("ACE_DLL::error"); - return this->last_error_; + if (this->error_) + return ACE_LIB_TEXT ("Error: check log for details."); + + return 0; } + + +#if 0 // Return the handle to the user either temporarily or forever, thus // orphaning it. If 0 means the user wants the handle forever and if 1 // means the user temporarily wants to take the handle. ACE_SHLIB_HANDLE -ACE_DLL::get_handle (int become_owner) +ACE_DLL::get_handle (int /*become_owner*/) { ACE_TRACE ("ACE_DLL::get_handle"); - // Since the caller is becoming the owner of the handle we lose - // rights to close it on destruction. The new controller has to do - // it explicitly. - if (become_owner) - this->close_on_destruction_ = 0; + // I'm only going to support this if I absolutely have to. + // in order to do that, we'd have to call ACE_OS::dlopen again to + // up the OS's refcount. :-( - // Return the handle requested by the user. - return this->handle_; + return ACE_SHLIB_INVALID_HANDLE; } // Set the handle for the DLL. By default, the object will be closed // before it is destroyed. int -ACE_DLL::set_handle (ACE_SHLIB_HANDLE handle, - int close_on_destruction) +ACE_DLL::set_handle (ACE_SHLIB_HANDLE /*handle*/, + int /*close_on_destruction*/) { ACE_TRACE ("ACE_DLL::set_handle"); - // Close the handle in use before accepting the next one. - if (this->close () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - ACE_LIB_TEXT ("%s\n"), this->error ()), - -1); - this->handle_ = handle; - this->close_on_destruction_ = close_on_destruction; + // Hmmm, how to do this... + // I don't see a way to get the name of the library associated with + // the handle, so either we use a dummy name or we try to compair + // it with other handles to see if you already have it... :-(( - return 0; + return -1; } +#endif /* 0 */ diff --git a/ace/DLL.h b/ace/DLL.h index 5501db0d2e2..b0276f8961e 100644 --- a/ace/DLL.h +++ b/ace/DLL.h @@ -21,6 +21,8 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ +class ACE_DLL_Handle; + /** * @class ACE_DLL * @@ -86,8 +88,9 @@ public: /// the <symbol_name> is returned. Otherwise, returns 0. void *symbol (const ACE_TCHAR *symbol_name); - /// Returns a pointer to a string explaining why <symbol> or <open> - /// failed. + /// Returns a pointer to a string explaining that an error occured. You + /// will need to consult the error log for the actual error string + /// returned by the OS. ACE_TCHAR *error (void) const; /** @@ -96,18 +99,12 @@ public: * won't call <close> when it goes out of scope, even if * <close_on_destruction> is set. */ - ACE_SHLIB_HANDLE get_handle (int become_owner = 0); + //ACE_SHLIB_HANDLE get_handle (int become_owner = 0); /// Set the handle for the DLL object. By default, the <close> operation on the /// object will be invoked before it is destroyed. - int set_handle (ACE_SHLIB_HANDLE handle, int close_on_destruction = 1); + //int set_handle (ACE_SHLIB_HANDLE handle, int close_on_destruction = 1); private: - /// Used internally to save the last error of a library operation so that - /// multiple subsequent calls to error() can be made safely. - void save_last_error (void); - - /// This is a handle to the DLL. - ACE_SHLIB_HANDLE handle_; /// Open mode. int open_mode_; @@ -121,17 +118,12 @@ private: /// automatically when the destructor runs. int close_on_destruction_; - /// This flag keeps track of whether the open method has ever been called on - /// any ACE_DLL object. Used by error() to decide whether or not to call - /// ACE_OS::dlerror(). On Linux, at least, calls to dlerror() prior to calling - /// dlopen() causes a seg-fault. - static sig_atomic_t open_called_; + ACE_DLL_Handle *dll_handle_; - /// This is the last error. - ACE_TCHAR *last_error_; + /// Flag to record if the last operation had an error. + int error_; // = Disallow copying and assignment since we don't handle these. - //ACE_UNIMPLEMENTED_FUNC (ACE_DLL (const ACE_DLL &)) ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_DLL &)) }; diff --git a/ace/Framework_Component.cpp b/ace/Framework_Component.cpp index 9a95eada6bb..9542063de01 100644 --- a/ace/Framework_Component.cpp +++ b/ace/Framework_Component.cpp @@ -11,6 +11,9 @@ ACE_RCSID(ace, Framework_Component, "$Id$") +#undef ACE_TRACE +#define ACE_TRACE(X) ACE_TRACE_IMPL(X) + ACE_Framework_Component::~ACE_Framework_Component (void) { ACE_TRACE ("ACE_Framework_Component::~ACE_Framework_Component"); @@ -22,6 +25,8 @@ ACE_Framework_Component::~ACE_Framework_Component (void) ACE_ALLOC_HOOK_DEFINE(ACE_Framework_Repository) +sig_atomic_t ACE_Framework_Repository::shutting_down_ = 0; + // Pointer to the Singleton instance. ACE_Framework_Repository *ACE_Framework_Repository::repository_ = 0; @@ -43,8 +48,6 @@ ACE_Framework_Repository::open (int size) -1); this->component_vector_ = temp; - //this->component_vector_ = ACE_const_cast (const ACE_Framework_Component **, - // temp); this->total_size_ = size; return 0; } @@ -55,6 +58,8 @@ ACE_Framework_Repository::close (void) ACE_TRACE ("ACE_Framework_Repository::close"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + this->shutting_down_ = 1; + if (this->component_vector_ != 0) { // Delete components in reverse order. @@ -65,8 +70,9 @@ ACE_Framework_Repository::close (void) ACE_Framework_Component *s = ACE_const_cast (ACE_Framework_Component *, this->component_vector_[i]); - --this->current_size_; - s->close_singleton (); + this->component_vector_[i] = 0; + if (s) + s->close_singleton (); } } @@ -75,6 +81,7 @@ ACE_Framework_Repository::close (void) this->current_size_ = 0; } + //ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("AFR::close: end\n"))); return 0; } @@ -164,18 +171,30 @@ ACE_Framework_Repository::remove_component (const ACE_TCHAR *name) int ACE_Framework_Repository::remove_dll_components (const ACE_TCHAR *dll_name) { - ACE_TRACE ("ACE_Framework_Repository::register_component"); + ACE_TRACE ("ACE_Framework_Repository::remove_dll_component"); + + if (this->shutting_down_) + return this->remove_dll_components_i (dll_name); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + return this->remove_dll_components_i (dll_name); +} + +int +ACE_Framework_Repository::remove_dll_components_i (const ACE_TCHAR *dll_name) +{ + ACE_TRACE ("ACE_Framework_Repository::remove_dll_components_i"); + int i; int retval = -1; - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("AFR::remove_dll_components ('%s')\n"), dll_name)); + //ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("AFR::remove_dll_components ('%s')\n"), dll_name)); for (i = 0; i < this->current_size_; i++) if (this->component_vector_[i] && ACE_OS_String::strcmp (this->component_vector_[i]->dll_name_, dll_name) == 0) { - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("AFR::remove_dll_c...()\n"))); + //ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("AFR::remove_dll_c...()\n"))); this->component_vector_[i]->close_singleton (); this->component_vector_[i] = 0; ++retval; @@ -193,7 +212,7 @@ ACE_Framework_Repository::dump (void) const ACE_Framework_Repository::ACE_Framework_Repository (int size) : current_size_ (0) { - ACE_TRACE ("ACE_Framework_Repository::ctor"); + ACE_TRACE ("ACE_Framework_Repository::ACE_Framework_Repository"); if (this->open (size) == -1) ACE_ERROR ((LM_ERROR, diff --git a/ace/Framework_Component.h b/ace/Framework_Component.h index 8a23b491b43..373ebec6199 100644 --- a/ace/Framework_Component.h +++ b/ace/Framework_Component.h @@ -146,6 +146,9 @@ private: /// Initialize the repository. ACE_Framework_Repository (int size = ACE_Framework_Repository::DEFAULT_SIZE); + /// Actually removes the dll components, must be called with locks held. + int remove_dll_components_i (const ACE_TCHAR *dll_name); + /// Contains all the framework components. ACE_Framework_Component **component_vector_; @@ -158,6 +161,12 @@ private: /// Pointer to a process-wide <ACE_Framework_Repository>. static ACE_Framework_Repository *repository_; + /// Flag set when repository is the process of shutting down. This + /// is necessary to keep from self-deadlocking since some of + /// the components might make calls back to the repository to + /// unload their components, e.g., ACE_DLL_Manager. + static sig_atomic_t shutting_down_; + #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) /// Synchronization variable for the MT_SAFE Repository ACE_Thread_Mutex lock_; diff --git a/ace/Makefile b/ace/Makefile index 8ba22fc9453..2015592a5be 100644 --- a/ace/Makefile +++ b/ace/Makefile @@ -185,6 +185,7 @@ IPC_FILES = \ MEM_Stream SVCCONF_FILES = \ DLL \ + DLL_Manager \ Dynamic_Service_Base \ Parse_Node \ Service_Config \ diff --git a/ace/Object_Manager.cpp b/ace/Object_Manager.cpp index f2d24b96b99..b1c41b87679 100644 --- a/ace/Object_Manager.cpp +++ b/ace/Object_Manager.cpp @@ -6,7 +6,6 @@ #endif /* ! ACE_LACKS_ACE_TOKEN */ #if defined (ACE_LACKS_ACE_SVCCONF) # include "ace/Thread_Manager.h" -# include "ace/Framework_Component.h" #else /* ! ACE_LACKS_ACE_SVCCONF */ # include "ace/Service_Manager.h" # include "ace/Service_Config.h" @@ -17,6 +16,7 @@ #include "ace/Synch.h" #include "ace/Malloc.h" #include "ace/Signal.h" +#include "ace/Framework_Component.h" #if !defined (__ACE_INLINE__) # include "ace/Object_Manager.i" @@ -605,8 +605,6 @@ ACE_Object_Manager::fini (void) #if defined (ACE_LACKS_ACE_SVCCONF) - ACE_Framework_Repository::close_singleton (); - # if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) ACE_Thread_Manager::close_singleton (); # endif /* ! ACE_THREAD_MANAGER_LACKS_STATICS */ @@ -619,8 +617,6 @@ ACE_Object_Manager::fini (void) #endif /* ! ACE_LACKS_ACE_SVCCONF */ - - // Close the main thread's TSS, including its Log_Msg instance. ACE_OS::cleanup_tss (1 /* main thread */); @@ -634,6 +630,10 @@ ACE_Object_Manager::fini (void) ACE_Service_Config::close (); #endif /* ! ACE_LACKS_ACE_SVCCONF */ + // This must come after closing ACE_Service_Config, since it will + // close down it's dlls--it manages ACE_DLL_Manager. + ACE_Framework_Repository::close_singleton (); + // Close the ACE_Allocator. ACE_Allocator::close_singleton (); diff --git a/ace/Parse_Node.cpp b/ace/Parse_Node.cpp index 08db977524c..e602f3bc43e 100644 --- a/ace/Parse_Node.cpp +++ b/ace/Parse_Node.cpp @@ -345,12 +345,14 @@ ACE_Location_Node::dll (void) return this->dll_; } +#if 0 ACE_SHLIB_HANDLE ACE_Location_Node::handle (void) { ACE_TRACE ("ACE_Location_Node::handle"); return this->dll_.get_handle (0); // Caller does not own the handle } +#endif /* 0 */ const ACE_TCHAR * ACE_Location_Node::pathname (void) const diff --git a/ace/Parse_Node.h b/ace/Parse_Node.h index f8f2094e107..16a16eccb0c 100644 --- a/ace/Parse_Node.h +++ b/ace/Parse_Node.h @@ -201,7 +201,7 @@ public: ACE_Location_Node (void); virtual void *symbol (ACE_Service_Object_Exterminator * = 0) = 0; virtual void set_symbol (void *h); - ACE_SHLIB_HANDLE handle (void); + //ACE_SHLIB_HANDLE handle (void); const ACE_DLL &dll (void); const ACE_TCHAR *pathname (void) const; void pathname (const ACE_TCHAR *h); diff --git a/ace/Service_Config.cpp b/ace/Service_Config.cpp index 7b75c157aa3..33cffa32988 100644 --- a/ace/Service_Config.cpp +++ b/ace/Service_Config.cpp @@ -11,7 +11,6 @@ #include "ace/Auto_Ptr.h" #include "ace/Reactor.h" #include "ace/Thread_Manager.h" -#include "ace/Framework_Component.h" #include "ace/Service_Config.h" #include "ace/XML_Svc_Conf.h" @@ -130,8 +129,6 @@ ACE_Service_Config::ACE_Service_Config (int ignore_static_svcs, // Initialize the Service Repository. ACE_Service_Repository::instance (size); - ACE_Framework_Repository::instance (); - // Initialize the ACE_Reactor (the ACE_Reactor should be the same // size as the ACE_Service_Repository). ACE_Reactor::instance (); @@ -858,8 +855,6 @@ ACE_Service_Config::close_singletons (void) { ACE_TRACE ("ACE_Service_Config::close_singletons"); - ACE_Framework_Repository::close_singleton (); - #if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) ACE_Thread_Manager::close_singleton (); #endif /* ! ACE_THREAD_MANAGER_LACKS_STATICS */ diff --git a/ace/Service_Object.cpp b/ace/Service_Object.cpp index 64ee5fd2317..1a4d931659b 100644 --- a/ace/Service_Object.cpp +++ b/ace/Service_Object.cpp @@ -11,9 +11,6 @@ ACE_RCSID(ace, Service_Object, "$Id$") -#undef ACE_TRACE -#define ACE_TRACE(X) ACE_TRACE_IMPL(X) - ACE_ALLOC_HOOK_DEFINE(ACE_Service_Object) ACE_ALLOC_HOOK_DEFINE(ACE_Service_Type) diff --git a/tests/Framework_Component_DLL.cpp b/tests/Framework_Component_DLL.cpp index c58b9520dc8..8f29b6461a3 100644 --- a/tests/Framework_Component_DLL.cpp +++ b/tests/Framework_Component_DLL.cpp @@ -8,6 +8,26 @@ ACE_RCSID (tests, Framework_Component_DLL, "$Id$") + +Simple_Service::Simple_Service (void) +{ + FRAMEWORK_COMPONENT_DLL_TRACE ("Simple_Service::Simple_Service"); +} + +Simple_Service::~Simple_Service (void) +{ + FRAMEWORK_COMPONENT_DLL_TRACE ("Simple_Service::~Simple_Service"); +} + +const ACE_TCHAR * +Simple_Service::dll_name (void) +{ + FRAMEWORK_COMPONENT_DLL_TRACE ("Simple_Service::dll_name"); + return 0; +} + +/***************************************************************************/ + /// This is just a simple server that can be loaded via the ACE /// Service Configuration framework and uses the singleton that /// also lives in this library. diff --git a/tests/Framework_Component_DLL.h b/tests/Framework_Component_DLL.h index a91c7fc9f38..4662fb4276e 100644 --- a/tests/Framework_Component_DLL.h +++ b/tests/Framework_Component_DLL.h @@ -32,20 +32,11 @@ class Framework_Component_DLL_Export Simple_Service { public: - Simple_Service (void) - { - FRAMEWORK_COMPONENT_DLL_TRACE ("Simple_Service::Simple_Service"); - } - virtual ~Simple_Service (void) - { - FRAMEWORK_COMPONENT_DLL_TRACE ("Simple_Service::~Simple_Service"); - } + Simple_Service (void); - virtual const ACE_TCHAR *dll_name (void) - { - FRAMEWORK_COMPONENT_DLL_TRACE ("Simple_Service::dll_name"); - return 0; - } + virtual ~Simple_Service (void); + + virtual const ACE_TCHAR *dll_name (void); }; diff --git a/tests/Framework_Component_Test.cpp b/tests/Framework_Component_Test.cpp index 226fdd65bb1..7215edeb14d 100644 --- a/tests/Framework_Component_Test.cpp +++ b/tests/Framework_Component_Test.cpp @@ -11,14 +11,14 @@ // via the Service Configurator framework, this test uses that framework // to load services from a dll that has a singleton based on ACE_DLL_Singleton. // When the dll is finally ready to be unloaded, the singleton will be -// automatically cleaned up just-in-time.// +// automatically cleaned up just-in-time. // // = AUTHOR // Don Hinton <dhinton@ieee.org> // // ============================================================================ -#include "Framework_Component_DLL.h" +//#include "Framework_Component_DLL.h" #include "ace/Service_Config.h" #include "ace/ARGV.h" #include "tests/test_config.h" @@ -36,8 +36,6 @@ ACE_TMAIN (int, ACE_TCHAR *[]) args.add (ACE_TEXT ("Framework_Component_Test")); args.add (ACE_TEXT ("-n")); args.add (ACE_TEXT ("-d")); - //args.add (ACE_TEXT ("-f")); - //args.add (ACE_TEXT ("Framework_Component_Test.conf")); args.add (ACE_TEXT ("-S")); args.add (ACE_TEXT ("\"dynamic Server_1 Service_Object * " "Framework_Component_DLL:_make_Server_1() 'xxx' \"")); @@ -45,12 +43,6 @@ ACE_TMAIN (int, ACE_TCHAR *[]) // Load it, should load a dll. ACE_Service_Config::open (args.argc (), args.argv ()); - // Now that the dll has been loaded, the singleton is available. - Simple_Service *ss = SS_SINGLETON::instance (); - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("Simple_Service lives in library: %s\n"), - ss->dll_name ())); - // Now load another service from the same library. ACE_Service_Config::process_directive (ACE_TEXT ("dynamic Server_2 Service_Object * " @@ -59,14 +51,12 @@ ACE_TMAIN (int, ACE_TCHAR *[]) // And unload the first one, should *not* unload the dll. ACE_Service_Config::process_directive (ACE_TEXT ("remove Server_1")); - // Make sure our singlton is still happy.. - // This will blow up now that simple service is deleted when the first - // ACE_DLL is destoyed--that's why we need to ref count the dlls ourselves - //ACE_DEBUG ((LM_DEBUG, - // ACE_TEXT ("Simple_Service is still alive in library: %s\n"), - // ss->dll_name ())); - - ACE_Service_Config::close (); + // And unload the second service. Since the ACE_DLL_Handle will no longer + // have any references, the ACE_DLL_Manager will apply it's current unloading + // strategy and either call ACE_OS::dlclose() immediately, schedule a timeout + // the the reactor to call dlclose() some time in the future, or keep the + // dll loaded until program termination. + ACE_Service_Config::process_directive (ACE_TEXT ("remove Server_2")); ACE_END_TEST; return 0; |