Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

ACE_DLL_Handle Class Reference

Provides an abstract interface for handling various DLL operations. More...

#include <DLL_Manager.h>

List of all members.

Public Methods

 ACE_DLL_Handle (void)
 Default construtor. More...

 ~ACE_DLL_Handle (void)
 Destructor. More...

const ACE_TCHARdll_name () const
 Returns the name of the shared library (without prefixes or suffixes). More...

int open (const ACE_TCHAR *dll_name, int open_mode, ACE_SHLIB_HANDLE handle)
int close (int unload=0)
 Call to close the DLL object. If unload = 0, it only decrements the refcount, but if unload = 1, then it will actually unload the library when the refcount == 0;. More...

sig_atomic_t refcount (void) const
 Return the current refcount. More...

void * symbol (const ACE_TCHAR *symbol_name, int ignore_errors=0)
 If <symbol_name> is in the symbol table of the DLL a pointer to the <symbol_name> is returned. Otherwise, returns 0. Set the ignore_errors flag to supress logging errors if symbol_name isn't found. This is nice if you just want to probe a dll to see what's available, since missing functions in that case aren't really errors. More...

ACE_SHLIB_HANDLE get_handle (int become_owner=0)

Private Methods

auto_ptr< ACE_TStringerror (void)
 Returns a pointer to a string explaining why <symbol> or <open> failed. This is used internal to print out the error to the log, but since this object is shared, we can't store or return the error to the caller. More...

 ACE_DLL_Handle (const ACE_DLL_Handle &)
void operator= (const ACE_DLL_Handle &)

Private Attributes

sig_atomic_t refcount_
ACE_TCHARdll_name_
 Name of the shared library. More...

ACE_SHLIB_HANDLE handle_
 Handle to the actual library loaded by the OS. More...


Static Private Attributes

sig_atomic_t open_called_ = 0
 Keeps track of whether or not open() has ever been called. This helps get around problem on Linux, and perhaps other OS's, that seg-fault if dlerror() is called before the ld library has been initialized by a call to dlopen(). More...


Detailed Description

Provides an abstract interface for handling various DLL operations.

This class is an wrapper over the various methods for utilizing a dynamically linked library (DLL), which is called a shared library on some platforms. It is refcounted and managed by ACE_DLL_Manager, so there will only be a single instance of this class for each dll loaded, no matter how many instances of ACE_DLL an application has open. Operations <open>, <close>, and <symbol> have been implemented to help opening/closing and extracting symbol information from a DLL, respectively.

Most of this class came from the original ACE_DLL class. ACE_DLL is now just an interface that passed all it's calls either directly or via ACE_DLL_Manager to this class for execution.

Definition at line 50 of file DLL_Manager.h.


Constructor & Destructor Documentation

ACE_DLL_Handle::ACE_DLL_Handle void   
 

Default construtor.

Definition at line 21 of file DLL_Manager.cpp.

References ACE_SHLIB_INVALID_HANDLE, and ACE_TRACE.

00022   : refcount_ (0),
00023     dll_name_ (0),
00024     handle_ (ACE_SHLIB_INVALID_HANDLE)
00025 {
00026   ACE_TRACE ("ACE_DLL_Handle::ACE_DLL_Handle");
00027 }

ACE_DLL_Handle::~ACE_DLL_Handle void   
 

Destructor.

Definition at line 29 of file DLL_Manager.cpp.

References ACE_TRACE, close, and dll_name_.

00030 {
00031   ACE_TRACE ("ACE_DLL_Handle::~ACE_DLL_Handle");
00032   this->close (1);
00033   delete[] this->dll_name_;
00034 }

ACE_DLL_Handle::ACE_DLL_Handle const ACE_DLL_Handle &    [private]
 


Member Function Documentation

int ACE_DLL_Handle::close int    unload = 0
 

Call to close the DLL object. If unload = 0, it only decrements the refcount, but if unload = 1, then it will actually unload the library when the refcount == 0;.

Definition at line 124 of file DLL_Manager.cpp.

References ACE_DEBUG, ACE_ERROR_RETURN, ACE_GUARD_RETURN, ACE_LIB_TEXT, ACE_MT, ACE_SHLIB_INVALID_HANDLE, ACE_TRACE, ACE::debug, ACE_OS::dlclose, handle_, ACE_Framework_Repository::instance, LM_DEBUG, LM_ERROR, refcount_, and ACE_Framework_Repository::remove_dll_components.

Referenced by ACE_DLL_Manager::unload_dll, ACE_DLL_Manager::unload_policy, and ~ACE_DLL_Handle.

00125 {
00126   ACE_TRACE ("ACE_DLL_Handle::close");
00127   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00128 
00129   int retval = 0;
00130 
00131   // Since we don't actually unload the dll as soon as the refcount
00132   // reaches zero, we need to make sure we don't decrement it below
00133   // zero.
00134   if (this->refcount_ > 0)
00135     --this->refcount_;
00136   else
00137     this->refcount_ = 0;
00138 
00139   if (this->refcount_ == 0 &&
00140       this->handle_ != ACE_SHLIB_INVALID_HANDLE &&
00141       unload == 1)
00142     {
00143       if (ACE::debug ())
00144         ACE_DEBUG ((LM_DEBUG,
00145                     ACE_LIB_TEXT ("ACE_DLL_Handle::close: unloading %s\n"),
00146                     this->dll_name_));
00147 
00148       ACE_Framework_Repository* frPtr= ACE_Framework_Repository::instance ();
00149       
00150       if (frPtr)
00151       {
00152          frPtr->remove_dll_components (this->dll_name_);
00153       }
00154       
00155       retval = ACE_OS::dlclose (this->handle_);
00156       this->handle_ = ACE_SHLIB_INVALID_HANDLE;
00157     }
00158 
00159   if (retval != 0)
00160     ACE_ERROR_RETURN ((LM_ERROR,
00161                        ACE_LIB_TEXT ("ACE_DLL_Handle::close error: \"%s\"."),
00162                        this->error ()->c_str ()),
00163                       retval);
00164   return retval;
00165 }

const ACE_TCHAR * ACE_DLL_Handle::dll_name   const
 

Returns the name of the shared library (without prefixes or suffixes).

Definition at line 37 of file DLL_Manager.cpp.

References ACE_TRACE, and dll_name_.

Referenced by open.

00038 {
00039   ACE_TRACE ("ACE_DLL_Handle::dll_name");
00040   return this->dll_name_;
00041 }

auto_ptr< ACE_TString > ACE_DLL_Handle::error void    [private]
 

Returns a pointer to a string explaining why <symbol> or <open> failed. This is used internal to print out the error to the log, but since this object is shared, we can't store or return the error to the caller.

Definition at line 228 of file DLL_Manager.cpp.

References ACE_LIB_TEXT, ACE_TCHAR, ACE_TRACE, ACE_TString, ACE_OS::dlerror, and error.

Referenced by error, and symbol.

00229 {
00230   ACE_TRACE ("ACE_DLL_Handle::error");
00231   const ACE_TCHAR *error = ACE_OS::dlerror ();
00232   auto_ptr<ACE_TString> str
00233     (new ACE_TString (error ? error : ACE_LIB_TEXT ("no error")));
00234   return str;
00235 }

ACE_SHLIB_HANDLE ACE_DLL_Handle::get_handle int    become_owner = 0
 

Return the handle to the caller. If <become_owner> is non-0 then caller assumes ownership of the handle so we decrement the retcount.

Definition at line 196 of file DLL_Manager.cpp.

References ACE_DEBUG, ACE_ERROR_RETURN, ACE_GUARD_RETURN, ACE_LIB_TEXT, ACE_MT, ACE_SHLIB_HANDLE, ACE_SHLIB_INVALID_HANDLE, ACE_TRACE, handle_, LM_DEBUG, LM_ERROR, and refcount_.

Referenced by ACE_DLL::get_handle.

00197 {
00198   ACE_TRACE ("ACE_DLL_Handle::get_handle");
00199   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00200 
00201   ACE_SHLIB_HANDLE handle = ACE_SHLIB_INVALID_HANDLE;
00202 
00203   if (this->refcount_ == 0 && become_owner != 0)
00204     ACE_ERROR_RETURN ((LM_ERROR,
00205                        ACE_LIB_TEXT ("ACE_DLL_Handle::get_handle: ")
00206                        ACE_LIB_TEXT ("cannot become owner, refcount == 0.\n")),
00207                       ACE_SHLIB_INVALID_HANDLE);
00208   else if (become_owner != 0)
00209     {
00210       handle = this->handle_;
00211       if (--this->refcount_ == 0)
00212         this->handle_ = ACE_SHLIB_INVALID_HANDLE;
00213     }
00214 
00215   ACE_DEBUG ((LM_DEBUG,
00216               ACE_LIB_TEXT ("ACE_DLL_Handle::get_handle: ")
00217               ACE_LIB_TEXT ("handle %s, refcount %d\n"),
00218               this->handle_ == ACE_SHLIB_INVALID_HANDLE ?
00219                 ACE_LIB_TEXT ("invalid") : ACE_LIB_TEXT ("valid"),
00220               this->refcount_));
00221 
00222   return handle;
00223 }

int ACE_DLL_Handle::open const ACE_TCHAR   dll_name,
int    open_mode,
ACE_SHLIB_HANDLE    handle
 

This method opens and dynamically links <dll_name>. The default mode is <RTLD_LAZY>, which loads identifier symbols but not the symbols for functions, which are loaded dynamically on-demand. Other supported modes include: <RTLD_NOW>, which performs all necessary relocations when <dll_name> is first loaded and <RTLD_GLOBAL>, which makes symbols available for relocation processing of any other DLLs. Returns -1 on failure and 0 on success.

Definition at line 44 of file DLL_Manager.cpp.

References ACE_DEBUG, ACE_ERROR_RETURN, ACE_GUARD_RETURN, ACE_LIB_TEXT, ACE_MT, ACE_SHLIB_HANDLE, ACE_SHLIB_INVALID_HANDLE, ACE_TCHAR, ACE_TRACE, ACE::debug, dll_name, dll_name_, ACE_OS::dlopen, handle_, ACE_Lib_Find::ldfind, LM_DEBUG, LM_ERROR, MAXPATHLEN, open_called_, refcount_, ACE_OS_String::strcat, ACE_OS_String::strcmp, ACE::strnew, and ACE_OS_String::strstr.

Referenced by ACE_DLL_Manager::open_dll.

00047 {
00048   ACE_TRACE ("ACE_DLL_Handle::open");
00049   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00050 
00051   //ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("dll_name: %s; open_mode: %d \n"),
00052   //            dll_name,
00053   //            open_mode));
00054 
00055   if (this->dll_name_)
00056     {
00057       // Once dll_name_ has been set, it can't be changed..
00058       if (ACE_OS_String::strcmp (this->dll_name_, dll_name) != 0)
00059         ACE_ERROR_RETURN ((LM_ERROR,
00060                            ACE_LIB_TEXT ("ACE_DLL_Handle::open: error, ")
00061                            ACE_LIB_TEXT ("tried to reopen %s with name %s\n"),
00062                            this->dll_name_, dll_name),
00063                           -1);
00064     }
00065   else
00066     this->dll_name_ = ACE::strnew (dll_name);
00067 
00068   if (!this->open_called_)
00069     this->open_called_ = 1;
00070 
00071   // If it hasn't been loaded yet, go ahead and do that now.
00072   if (this->handle_ == ACE_SHLIB_INVALID_HANDLE)
00073     {
00074       if (handle)
00075         this->handle_ = handle;
00076       else
00077         {
00078           if (ACE::debug ())
00079             ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_DLL_Handle::open: calling dlopen on ")
00080                         ACE_LIB_TEXT ("\"%s\"\n"), dll_name));
00081           // Find out where the library is
00082           ACE_TCHAR dll_pathname[MAXPATHLEN + 1];
00083 
00084           // Transform the pathname into the appropriate dynamic link library
00085           // by searching the ACE_LD_SEARCH_PATH.
00086           ACE_Lib_Find::ldfind (dll_name,
00087                                 dll_pathname,
00088                                 (sizeof dll_pathname / sizeof (ACE_TCHAR)));
00089 
00090           // The ACE_SHLIB_HANDLE object is obtained.
00091           this->handle_ = ACE_OS::dlopen (dll_pathname,
00092                                           open_mode);
00093 
00094 #if defined (AIX)
00095           if (this->handle_ == ACE_SHLIB_INVALID_HANDLE)
00096             {
00097               // AIX often puts the shared library file (most often named shr.o)
00098               // inside an archive library. If this is an archive library
00099               // name, then try appending [shr.o] and retry.
00100               if (0 != ACE_OS_String::strstr (dll_pathname, ACE_LIB_TEXT (".a")))
00101                 {
00102                   ACE_OS_String::strcat (dll_pathname, ACE_LIB_TEXT ("(shr.o)"));
00103                   open_mode |= RTLD_MEMBER;
00104                   this->handle_ = ACE_OS::dlopen (dll_pathname, open_mode);
00105                 }
00106             }
00107 #endif /* AIX */
00108 
00109           if (this->handle_ == ACE_SHLIB_INVALID_HANDLE)
00110             {
00111               ACE_ERROR_RETURN ((LM_ERROR,
00112                                  ACE_LIB_TEXT ("ACE_DLL_Manager_Ex::open: Invalid handle: %s\n"),
00113                                  this->error ()->c_str ()),
00114                                 -1);
00115             }
00116         }
00117     }
00118 
00119   ++this->refcount_;
00120   return 0;
00121 }

void ACE_DLL_Handle::operator= const ACE_DLL_Handle &    [private]
 

sig_atomic_t ACE_DLL_Handle::refcount void    const
 

Return the current refcount.

Definition at line 168 of file DLL_Manager.cpp.

References refcount_.

Referenced by ACE_DLL_Manager::unload_policy.

00169 {
00170   return this->refcount_;
00171 }

void * ACE_DLL_Handle::symbol const ACE_TCHAR   symbol_name,
int    ignore_errors = 0
 

If <symbol_name> is in the symbol table of the DLL a pointer to the <symbol_name> is returned. Otherwise, returns 0. Set the ignore_errors flag to supress logging errors if symbol_name isn't found. This is nice if you just want to probe a dll to see what's available, since missing functions in that case aren't really errors.

Definition at line 174 of file DLL_Manager.cpp.

References ACE_ERROR_RETURN, ACE_GUARD_RETURN, ACE_LIB_TEXT, ACE_MT, ACE_TCHAR, ACE_TRACE, ACE_OS::dlsym, error, ACE_Auto_Basic_Array_Ptr::get, ACE_Lib_Find::ldname, and LM_ERROR.

Referenced by ACE_DLL::symbol, and ACE_DLL_Manager::unload_dll.

00175 {
00176   ACE_TRACE ("ACE_DLL_Handle::symbol");
00177   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00178 
00179   ACE_Auto_Array_Ptr <ACE_TCHAR> auto_name (ACE_Lib_Find::ldname (sym_name));
00180 
00181   void *sym =  ACE_OS::dlsym (this->handle_, auto_name.get ());
00182 
00183   // Linux says that the symbol could be null and that it isn't an error.
00184   // So you should check the error message also, but since null symbols
00185   // won't do us much good anyway, let's still report an error.
00186   if (!sym && ignore_errors != 1)
00187     ACE_ERROR_RETURN ((LM_ERROR,
00188                        ACE_LIB_TEXT ("ACE_DLL_Handle::symbol (\"%s\") \"%s\"."),
00189                        auto_name.get (), this->error ()->c_str ()),
00190                       0);
00191 
00192   return sym;
00193 }


Member Data Documentation

ACE_TCHAR* ACE_DLL_Handle::dll_name_ [private]
 

Name of the shared library.

Definition at line 110 of file DLL_Manager.h.

Referenced by dll_name, open, and ~ACE_DLL_Handle.

ACE_SHLIB_HANDLE ACE_DLL_Handle::handle_ [private]
 

Handle to the actual library loaded by the OS.

Definition at line 113 of file DLL_Manager.h.

Referenced by close, get_handle, and open.

sig_atomic_t ACE_DLL_Handle::open_called_ = 0 [static, private]
 

Keeps track of whether or not open() has ever been called. This helps get around problem on Linux, and perhaps other OS's, that seg-fault if dlerror() is called before the ld library has been initialized by a call to dlopen().

Definition at line 19 of file DLL_Manager.cpp.

Referenced by open.

sig_atomic_t ACE_DLL_Handle::refcount_ [private]
 

Definition at line 107 of file DLL_Manager.h.

Referenced by close, get_handle, open, and refcount.


The documentation for this class was generated from the following files:
Generated on Mon Jun 16 12:47:14 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002