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

DLL_Manager.h

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

Generated on Mon Jun 16 11:19:37 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002