diff options
Diffstat (limited to 'ace/Svcconf/DLL.cpp')
-rw-r--r-- | ace/Svcconf/DLL.cpp | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/ace/Svcconf/DLL.cpp b/ace/Svcconf/DLL.cpp new file mode 100644 index 00000000000..622cbe081ab --- /dev/null +++ b/ace/Svcconf/DLL.cpp @@ -0,0 +1,188 @@ +// DLL.cpp +// $Id$ + +#include "ace/DLL.h" + +#include "ace/Log_Msg.h" +#include "ace/ACE.h" + +ACE_RCSID(ace, DLL, "$Id$") + +// Default constructor. Also, by default, the object will be closed +// before it is destroyed. + +ACE_DLL::ACE_DLL (int close_on_destruction) + : handle_ (ACE_SHLIB_INVALID_HANDLE), + close_on_destruction_ (close_on_destruction) +{ +} + +// If the library name and the opening mode are specified than on +// object creation the library is implicitly opened. + +ACE_DLL::ACE_DLL (const ACE_TCHAR *dll_name, + int open_mode, + int close_on_destruction) + : handle_ (ACE_OS::dlopen (dll_name, + open_mode)), + close_on_destruction_ (close_on_destruction) +{ + if (this->handle_ == ACE_SHLIB_INVALID_HANDLE) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%s\n"), + this->error ())); +} + +// The library is closed before the class gets destroyed depending on +// the close_on_destruction value specified which is stored in +// close_on_destruction_. + +ACE_DLL::~ACE_DLL (void) +{ + // CLose the library only if it hasn't been already. + this->close (); +} + +// This method opens the library based on the mode specified using the +// ACE_SHLIB_HANDLE which is obtained on making the ACE_OS::dlopen call. +// The default mode is: +// RTLD_LAZY Only references to data symbols are relocate when the +// object is first loaded. +// The other modes include: +// RTLD_NOW All necessary relocations are performed when the +// object is first loaded. +// RTLD_GLOBAL The object symbols are made available for the +// relocation processing of any other object. + +int +ACE_DLL::open (const ACE_TCHAR *dll_filename, + int open_mode, + int close_on_destruction) +{ + // This check is necessary as the library could be opened more than + // once without closing it which would cause handle memory leaks. + this->close (); + + // Reset the flag + 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. + int result = ACE_Lib_Find::ldfind (dll_filename, + dll_pathname, + (sizeof dll_pathname / sizeof (ACE_TCHAR))); + // Check for errors + if (result != 0) + return result; + + // The ACE_SHLIB_HANDLE object is obtained. + this->handle_ = ACE_OS::dlopen (dll_pathname, + open_mode); + + if (this->handle_ == ACE_SHLIB_INVALID_HANDLE) + { +#if defined (AIX) + do + { + // 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"))) + { + ACE_OS_String::strcat (dll_pathname, ACE_LIB_TEXT ("(shr.o)")); + open_mode |= RTLD_MEMBER; + this->handle_ = ACE_OS::dlopen (dll_pathname, open_mode); + if (this->handle_ != ACE_SHLIB_INVALID_HANDLE) + break; // end up returning 0 + } + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("%s\n"), this->error ()), + -1); + } + while (0); +#else + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("%s\n"), this->error ()), + -1); +#endif /* AIX */ + } + + return 0; +} + +// The symbol refernce of the name specified is obtained. + +void * +ACE_DLL::symbol (const ACE_TCHAR *sym_name) +{ + return ACE_OS::dlsym (this->handle_, sym_name); +} + +// The library is closed using the ACE_SHLIB_HANDLE obejct. i.e. The +// shared object is now disassociated form the current process. + +int +ACE_DLL::close (void) +{ + int retval = 0; + + // 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) + { + retval = ACE_OS::dlclose (this->handle_); + } + + this->handle_ = ACE_SHLIB_INVALID_HANDLE; + return retval; +} + +// This method is used on error in an library operation. + +ACE_TCHAR * +ACE_DLL::error (void) +{ + return ACE_OS::dlerror (); +} + +// 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) +{ + // 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; + + // Return the handle requested by the user. + return this->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) +{ + // 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; + + return 0; +} |