DLL_Manager.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    DLL_Manager.h
00006  *
00007  *  DLL_Manager.h,v 4.21 2006/06/26 08:25:50 jwillemsen Exp
00008  *
00009  *  @author Don Hinton <dhinton@ieee.org>
00010  */
00011 //=============================================================================
00012 
00013 
00014 #ifndef ACE_DLL_MANAGER_H
00015 #define ACE_DLL_MANAGER_H
00016 #include /**/ "ace/pre.h"
00017 
00018 #include "ace/ACE_export.h"
00019 
00020 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00021 # pragma once
00022 #endif /* ACE_LACKS_PRAGMA_ONCE */
00023 
00024 #include "ace/Auto_Ptr.h"
00025 #include "ace/Containers_T.h"
00026 #include "ace/SStringfwd.h"
00027 #include "ace/os_include/os_dlfcn.h"
00028 
00029 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00030 #  include "ace/Thread_Mutex.h"
00031 #endif /* ACE_MT_SAFE */
00032 
00033 #define ACE_DEFAULT_DLL_MANAGER_SIZE 1024
00034 
00035 
00036 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00037 
00038 /**
00039  * @class ACE_DLL_Handle
00040  *
00041  * @brief Provides an abstract interface for handling various DLL
00042  * operations.
00043  *
00044  * This class is an wrapper over the various methods for utilizing
00045  * a dynamically linked library (DLL), which is called a shared
00046  * library on some platforms.  It is refcounted and managed by
00047  * ACE_DLL_Manager, so there will only be a single instance of this
00048  * class for each dll loaded, no matter how many instances of ACE_DLL
00049  * an application has open.  Operations <open>, <close>, and
00050  * <symbol> have been implemented to help opening/closing and
00051  * extracting symbol information from a DLL, respectively.
00052  *
00053  * Most of this class came from the original ACE_DLL class.
00054  * ACE_DLL is now just an interface that passed all it's calls
00055  * either directly or via ACE_DLL_Manager to this class for
00056  * execution.
00057  *
00058  */
00059 class ACE_Export ACE_DLL_Handle
00060 {
00061 public:
00062 
00063   /// Default construtor.
00064   ACE_DLL_Handle (void);
00065 
00066   /// Destructor.
00067   ~ACE_DLL_Handle (void);
00068 
00069   /// Returns the name of the shared library (without prefixes or suffixes).
00070   const ACE_TCHAR *dll_name () const;
00071 
00072   /**
00073    * This method opens and dynamically links @a dll_name.  The default
00074    * mode is <RTLD_LAZY>, which loads identifier symbols but not the
00075    * symbols for functions, which are loaded dynamically on-demand.
00076    * Other supported modes include: <RTLD_NOW>, which performs all
00077    * necessary relocations when @a dll_name is first loaded and
00078    * <RTLD_GLOBAL>, which makes symbols available for relocation
00079    * processing of any other DLLs.  Returns -1 on failure and 0 on
00080    * success.
00081    */
00082   int open (const ACE_TCHAR *dll_name,
00083             int open_mode,
00084             ACE_SHLIB_HANDLE handle);
00085 
00086   /// Call to close the DLL object.  If unload = 0, it only decrements
00087   /// the refcount, but if unload = 1, then it will actually unload
00088   /// the library when the refcount == 0;
00089   int close (int unload = 0);
00090 
00091   /// Return the current refcount.
00092   sig_atomic_t refcount (void) const;
00093 
00094   /// If @a symbol_name is in the symbol table of the DLL a pointer to
00095   /// the @a symbol_name is returned.  Otherwise, returns 0.  Set the
00096   /// ignore_errors flag to supress logging errors if symbol_name isn't
00097   /// found.  This is nice if you just want to probe a dll to see what's
00098   /// available, since missing functions in that case aren't really errors.
00099   void *symbol (const ACE_TCHAR *symbol_name, int ignore_errors = 0);
00100 
00101   /**
00102    * Return the handle to the caller.  If @a become_owner is non-0 then
00103    * caller assumes ownership of the handle so we decrement the retcount.
00104    */
00105   ACE_SHLIB_HANDLE get_handle (int become_owner = 0);
00106 
00107 private:
00108 
00109   /// Returns a pointer to a string explaining why <symbol> or <open>
00110   /// failed.  This is used internal to print out the error to the log,
00111   /// but since this object is shared, we can't store or return the error
00112   /// to the caller.
00113   auto_ptr <ACE_TString> error (void);
00114 
00115   // Builds array of DLL names to try to dlopen, based on platform
00116   // and configured DLL prefixes/suffixes.
00117   // Returns the array of names to try in try_names.
00118   void get_dll_names (const ACE_TCHAR *dll_name,
00119                       ACE_Array<ACE_TString> &try_names);
00120 
00121   // Disallow copying and assignment since we don't handle them.
00122   ACE_DLL_Handle (const ACE_DLL_Handle &);
00123   void operator= (const ACE_DLL_Handle &);
00124 
00125 private:
00126 
00127   // Keep track of how many ACE_DLL objects have a reference to this
00128   // dll.
00129   sig_atomic_t refcount_;
00130 
00131   /// Name of the shared library.
00132   ACE_TCHAR *dll_name_;
00133 
00134   /// Handle to the actual library loaded by the OS.
00135   ACE_SHLIB_HANDLE handle_;
00136 
00137   /// Keeps track of whether or not open() has ever been called.  This
00138   /// helps get around problem on Linux, and perhaps other OS's, that
00139   /// seg-fault if dlerror() is called before the ld library has been
00140   /// initialized by a call to dlopen().
00141   static sig_atomic_t open_called_;
00142 
00143 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00144   /// Synchronization variable for the MT_SAFE Repository
00145   ACE_Thread_Mutex lock_;
00146 #endif /* ACE_MT_SAFE */
00147 };
00148 
00149 class ACE_Framework_Repository;
00150 
00151 /**
00152  * @class ACE_DLL_Manager
00153  *
00154  * @brief This class is a singleton and serves as a factory and
00155  * repository for instances of ACE_DLL_Handle.
00156  *
00157  * This class is a singleton whose lifetime is managed by the
00158  * ACE_Framework_Repository.  Although it is normally meant to be
00159  * used directly only by ACE_DLL, applications can call the unload_policy()
00160  * methods in order get/set the the dll unload policy.  Unload policies include
00161  * per_process/per-dll and eager/lazy.  Dlls can export set their own policy
00162  * by using the ACE_DLL_UNLOAD_POLICY macro found in config-all.h.  If a dll
00163  * choses to set an unload policy, it will be used when the per-dll policy
00164  * (the default) is in effect.  If the per-dll policy is in effect and a dll
00165  * has not chosen to set a policy, the current per-process policy will be
00166  * used.
00167  *
00168  * The following policy macros are provided in config-all.h:
00169  *
00170  *  ACE_DLL_UNLOAD_POLICY_PER_PROCESS - Per-process policy that unloads dlls
00171  *  eagerly.
00172  *
00173  *  ACE_DLL_UNLOAD_POLICY_PER_DLL - Apply policy on a per-dll basis.  If the
00174  *  dll doesn't use one of the macros below, the current per-process policy
00175  *  will be used.
00176  *
00177  *  ACE_DLL_UNLOAD_POLICY_LAZY - Don't unload dll when refcount reaches
00178  *  zero, i.e., wait for either an explicit unload request or program exit.
00179  *
00180  *  ACE_DLL_UNLOAD_POLICY_DEFAULT - Default policy allows dlls to control
00181  *  their own destinies, but will unload those that don't make a choice eagerly.
00182  *
00183  */
00184 class ACE_Export ACE_DLL_Manager
00185 {
00186 public:
00187   friend class ACE_Framework_Repository;
00188   friend class ACE_Object_Manager;
00189 
00190   enum
00191   {
00192     DEFAULT_SIZE = ACE_DEFAULT_DLL_MANAGER_SIZE
00193   };
00194 
00195   /// Return a unique instance
00196   static ACE_DLL_Manager *instance (int size = ACE_DLL_Manager::DEFAULT_SIZE);
00197 
00198   /// Factory for ACE_DLL_Handle objects.  If one already exits,
00199   /// its refcount is incremented.
00200   ACE_DLL_Handle *open_dll (const ACE_TCHAR *dll_name,
00201                             int openmode,
00202                             ACE_SHLIB_HANDLE handle);
00203 
00204   /// Close the underlying dll.  Decrements the refcount.
00205   int close_dll (const ACE_TCHAR *dll_name);
00206 
00207   /// Returns the current per-process UNLOAD_POLICY.
00208   u_long unload_policy (void) const;
00209 
00210   /// Set the per-process UNLOAD_POLICY.  If the policy is changed from
00211   /// LAZY to EAGER, then it will also unload any dlls with zero
00212   /// refcounts.
00213   void unload_policy (u_long unload_policy);
00214 
00215 protected:
00216 
00217   /// Default constructor.
00218   ACE_DLL_Manager (int size = ACE_DLL_Manager::DEFAULT_SIZE);
00219 
00220   /// Destructor.
00221   ~ACE_DLL_Manager (void);
00222 
00223   // Allocate handle_vector_.
00224   int open (int size);
00225 
00226   // Close all open dlls and deallocate memory.
00227   int close (void);
00228 
00229   // Find dll in handle_vector_.
00230   ACE_DLL_Handle *find_dll (const ACE_TCHAR *dll_name) const;
00231 
00232   // Applies strategy for unloading dll.
00233   int unload_dll (ACE_DLL_Handle *dll_handle, int force_unload = 0);
00234 
00235 private:
00236 
00237   /// Close the singleton instance.
00238   static void close_singleton (void);
00239 
00240   // Disallow copying and assignment since we don't handle these.
00241   ACE_DLL_Manager (const ACE_DLL_Manager &);
00242   void operator= (const ACE_DLL_Manager &);
00243 
00244 private:
00245 
00246   /// Vector containing all loaded handle objects.
00247   ACE_DLL_Handle **handle_vector_;
00248 
00249   /// Current number of handles.
00250   int current_size_;
00251 
00252   /// Maximum number of handles.
00253   int total_size_;
00254 
00255   /// Unload strategy.
00256   u_long unload_policy_;
00257 
00258   /// Pointer to a process-wide <ACE_DLL_Manager>.
00259   static ACE_DLL_Manager *instance_;
00260 
00261 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00262   /// Synchronization variable for the MT_SAFE Repository
00263   ACE_Thread_Mutex lock_;
00264 #endif /* ACE_MT_SAFE */
00265 
00266 };
00267 
00268 ACE_END_VERSIONED_NAMESPACE_DECL
00269 
00270 #include /**/ "ace/post.h"
00271 #endif /* ACE_DLL_MANAGER_H */

Generated on Thu Nov 9 09:41:50 2006 for ACE by doxygen 1.3.6