summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordhinton <dhinton@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2002-05-23 18:09:54 +0000
committerdhinton <dhinton@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2002-05-23 18:09:54 +0000
commitadbbcb5245b1aad5a91c77af56473d694518e6b0 (patch)
treec2c80b11e4d29995f44d6630fe5e2a505ec84d80
parent0372b477f08e3d7649b4610b492ec6509a8b92a2 (diff)
downloadATCD-adbbcb5245b1aad5a91c77af56473d694518e6b0.tar.gz
ChangeLogTag:Thu May 23 17:39:02 UTC 2002 Don Hinton <dhinton@ieee.org>
-rw-r--r--ChangeLog49
-rw-r--r--ChangeLogs/ChangeLog-02a49
-rw-r--r--ChangeLogs/ChangeLog-03a49
-rw-r--r--ace/DLL.cpp199
-rw-r--r--ace/DLL.h28
-rw-r--r--ace/Framework_Component.cpp35
-rw-r--r--ace/Framework_Component.h9
-rw-r--r--ace/Makefile1
-rw-r--r--ace/Object_Manager.cpp10
-rw-r--r--ace/Parse_Node.cpp2
-rw-r--r--ace/Parse_Node.h2
-rw-r--r--ace/Service_Config.cpp5
-rw-r--r--ace/Service_Object.cpp3
-rw-r--r--tests/Framework_Component_DLL.cpp20
-rw-r--r--tests/Framework_Component_DLL.h17
-rw-r--r--tests/Framework_Component_Test.cpp26
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;