Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / DLL_Manager.h
blob6adcc2ceaa8c5e7ccf15ce952269c30629935f81
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file DLL_Manager.h
7 * @author Don Hinton <dhinton@ieee.org>
8 */
9 //=============================================================================
11 #ifndef ACE_DLL_MANAGER_H
12 #define ACE_DLL_MANAGER_H
13 #include /**/ "ace/pre.h"
15 #include /**/ "ace/ACE_export.h"
17 #if !defined (ACE_LACKS_PRAGMA_ONCE)
18 # pragma once
19 #endif /* ACE_LACKS_PRAGMA_ONCE */
21 #include "ace/Containers_T.h"
22 #include "ace/SString.h"
23 #include "ace/os_include/os_dlfcn.h"
25 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
26 # include "ace/Thread_Mutex.h"
27 #endif /* ACE_MT_SAFE */
29 #define ACE_DEFAULT_DLL_MANAGER_SIZE 1024
31 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
33 /**
34 * @class ACE_DLL_Handle
36 * @brief Provides an abstract interface for handling various DLL
37 * operations.
39 * This class is an wrapper over the various methods for utilizing a
40 * dynamically linked library (DLL), which is called a shared library
41 * on some platforms. It is refcounted and managed by
42 * ACE_DLL_Manager, so there will only be a single instance of this
43 * class for each dll loaded, no matter how many instances of ACE_DLL
44 * an application has open. Operations open(), close(), and symbol()
45 * have been implemented to help opening/closing and extracting symbol
46 * information from a DLL, respectively.
48 * Most of this class came from the original ACE_DLL class. ACE_DLL
49 * is now just an interface that passed all it's calls either directly
50 * or via ACE_DLL_Manager to this class for execution.
52 class ACE_Export ACE_DLL_Handle
54 public:
55 /// Error stack. Fixed size should suffice. Ignores any errors exceeding the size.
56 typedef ACE_Fixed_Stack <ACE_TString, 10> ERROR_STACK;
58 /// Default constructor.
59 ACE_DLL_Handle ();
61 /// Destructor.
62 ~ACE_DLL_Handle ();
64 /// Returns the name of the shared library (without prefixes or suffixes).
65 const ACE_TCHAR *dll_name () const;
67 /**
68 * This method opens and dynamically links a library/DLL.
69 * @param dll_name The filename or path of the DLL to load. ACE will
70 * attempt to apply the platform's standard library/DLL prefixes
71 * and suffixes, allowing a simple, unadorned name to be passed
72 * regardless of platform. The set of name transforms is listed
73 * below. A @i decorator is a platform's name designator for a debug
74 * vs release build. For example, on Windows it is usually "d".
75 * @li Prefix + name + decorator + suffix
76 * @li Prefix + name + suffix
77 * @li Name + decorator + suffix
78 * @li Name + suffix
79 * @li Name
80 * Note that the transforms with @i decorator will be avoided if
81 * ACE is built with the @c ACE_DISABLE_DEBUG_DLL_CHECK config macro.
83 * @Note There is another mode for locating library/DLL files that
84 * was used in old versions of ACE. The alternate method builds
85 * more combinations of pathname by combining the names transforms
86 * above with locations listed in the platform's standard "path"
87 * locations (e.g., @c LD_LIBRARY_PATH). It can be enabled by building
88 * ACE with the @c ACE_MUST_HELP_DLOPEN_SEARCH_PATH config macro.
89 * Use of this option is discouraged since it avoids the standard
90 * platform search options and security mechanisms.
92 * @param open_mode Flags to alter the actions taken when loading the DLL.
93 * The possible values are:
94 * @li @c RTLD_LAZY (this the default): loads identifier symbols but
95 * not the symbols for functions, which are loaded dynamically
96 * on demand.
97 * @li @c RTLD_NOW: performs all necessary relocations when
98 * @a dll_name is first loaded
99 * @li @c RTLD_GLOBAL: makes symbols available for relocation
100 * processing of any other DLLs.
101 * @param handle If a value other than @c ACE_INVALID_HANDLE is supplied,
102 * this object is assigned the specified handle instead of attempting
103 * to open the specified @a dll_name.
104 * @param errors Optional address of an error stack to collect any errors
105 * encountered.
106 * @retval -1 On failure
107 * @retval 0 On success.
109 int open (const ACE_TCHAR *dll_name,
110 int open_mode,
111 ACE_SHLIB_HANDLE handle,
112 ERROR_STACK *errors = 0);
114 /// Call to close the DLL object. If unload = 0, it only decrements
115 /// the refcount, but if unload = 1, then it will actually unload
116 /// the library when the refcount == 0;
117 int close (int unload = 0);
119 /// Return the current refcount.
120 sig_atomic_t refcount () const;
122 /// If @a symbol_name is in the symbol table of the DLL a pointer to
123 /// the @a symbol_name is returned. Otherwise, returns 0. Set the
124 /// @a ignore_errors flag to suppress logging errors if @a symbol_name isn't
125 /// found. This is nice if you just want to probe a dll to see what's
126 /// available, since missing functions in that case aren't really errors.
127 void *symbol (const ACE_TCHAR *symbol_name, bool ignore_errors = false);
129 /// Resolves and returns any error encountered.
130 void *symbol (const ACE_TCHAR *symbol_name, bool ignore_errors,
131 ACE_TString &error);
134 * Return the handle to the caller. If @a become_owner is true then
135 * caller assumes ownership of the handle so we decrement the retcount.
137 ACE_SHLIB_HANDLE get_handle (bool become_owner = false);
139 ACE_ALLOC_HOOK_DECLARE;
141 private:
142 /// Returns a string explaining why <symbol> or <open>
143 /// failed in @a err. This is used internal to print out the error to the log,
144 /// but since this object is shared, we can't store or return the error
145 /// to the caller.
146 ACE_TString& error (ACE_TString& err);
148 /// Builds array of DLL names to try to dlopen, based on platform
149 /// and configured DLL prefixes/suffixes.
150 /// Returns the array of names to try in @a try_names.
151 void get_dll_names (const ACE_TCHAR *dll_name,
152 ACE_Array<ACE_TString> &try_names);
155 * This method opens and dynamically links a library/DLL.
156 * @param dll_name The filename or path of the DLL to load.
157 * @param open_mode Flags to alter the actions taken when loading the DLL.
158 * The possible values are:
159 * @li @c RTLD_LAZY (this the default): loads identifier symbols but
160 * not the symbols for functions, which are loaded dynamically
161 * on demand.
162 * @li @c RTLD_NOW: performs all necessary relocations when
163 * @a dll_name is first loaded
164 * @li @c RTLD_GLOBAL: makes symbols available for relocation
165 * processing of any other DLLs.
166 * @param errors Optional address of an error stack to collect any errors
167 * encountered.
168 * @retval false On failure
169 * @retval true On success
171 bool open_i (const ACE_TCHAR *dll_name, int open_mode, ERROR_STACK* errors);
173 ACE_DLL_Handle (const ACE_DLL_Handle &) = delete;
174 void operator= (const ACE_DLL_Handle &) = delete;
175 ACE_DLL_Handle (ACE_DLL_Handle &&) = delete;
176 void operator= (ACE_DLL_Handle &&) = delete;
178 private:
179 /// Keep track of how many ACE_DLL objects have a reference to this
180 /// dll.
181 sig_atomic_t refcount_;
183 /// Name of the shared library.
184 ACE_TCHAR *dll_name_;
186 /// Handle to the actual library loaded by the OS.
187 ACE_SHLIB_HANDLE handle_;
189 /// Keeps track of whether or not open() has ever been called. This
190 /// helps get around problem on Linux, and perhaps other OS's, that
191 /// seg-fault if dlerror() is called before the ld library has been
192 /// initialized by a call to dlopen().
193 static sig_atomic_t open_called_;
195 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
196 /// Synchronization variable for the MT_SAFE Repository
197 ACE_Thread_Mutex lock_;
198 #endif /* ACE_MT_SAFE */
201 class ACE_Framework_Repository;
204 * @class ACE_DLL_Manager
206 * @brief This class is a singleton and serves as a factory and
207 * repository for instances of ACE_DLL_Handle.
209 * This class is a singleton whose lifetime is managed by the
210 * ACE_Framework_Repository. Although it is normally meant to be
211 * used directly only by ACE_DLL, applications can call the unload_policy()
212 * methods in order get/set the the dll unload policy. Unload policies include
213 * per_process/per-dll and eager/lazy. Dlls can export set their own policy
214 * by using the ACE_DLL_UNLOAD_POLICY macro found in config-all.h. If a dll
215 * choses to set an unload policy, it will be used when the per-dll policy
216 * (the default) is in effect. If the per-dll policy is in effect and a dll
217 * has not chosen to set a policy, the current per-process policy will be
218 * used.
220 * The following policy macros are provided in config-all.h:
222 * ACE_DLL_UNLOAD_POLICY_PER_PROCESS - Per-process policy that unloads dlls
223 * eagerly.
225 * ACE_DLL_UNLOAD_POLICY_PER_DLL - Apply policy on a per-dll basis. If the
226 * dll doesn't use one of the macros below, the current per-process policy
227 * will be used.
229 * ACE_DLL_UNLOAD_POLICY_LAZY - Don't unload dll when refcount reaches
230 * zero, i.e., wait for either an explicit unload request or program exit.
232 * ACE_DLL_UNLOAD_POLICY_DEFAULT - Default policy allows dlls to control
233 * their own destinies, but will unload those that don't make a choice eagerly.
235 class ACE_Export ACE_DLL_Manager
237 public:
238 friend class ACE_Framework_Repository;
239 friend class ACE_Object_Manager;
241 enum
243 DEFAULT_SIZE = ACE_DEFAULT_DLL_MANAGER_SIZE
246 /// Return a unique instance
247 static ACE_DLL_Manager *instance (int size = ACE_DLL_Manager::DEFAULT_SIZE);
249 /// Factory for ACE_DLL_Handle objects. If one already exits,
250 /// its refcount is incremented.
251 ACE_DLL_Handle *open_dll (const ACE_TCHAR *dll_name,
252 int openmode,
253 ACE_SHLIB_HANDLE handle,
254 ACE_DLL_Handle::ERROR_STACK *errors = 0);
256 /// Close the underlying dll. Decrements the refcount.
257 int close_dll (const ACE_TCHAR *dll_name);
259 /// Returns the current per-process UNLOAD_POLICY.
260 u_long unload_policy () const;
262 /// Set the per-process UNLOAD_POLICY. If the policy is changed from
263 /// LAZY to EAGER, then it will also unload any dlls with zero
264 /// refcounts.
265 void unload_policy (u_long unload_policy);
267 ACE_ALLOC_HOOK_DECLARE;
269 protected:
270 /// Default constructor.
271 ACE_DLL_Manager (int size = ACE_DLL_Manager::DEFAULT_SIZE);
273 /// Destructor.
274 ~ACE_DLL_Manager ();
276 /// Allocate handle_vector_.
277 int open (int size);
279 /// Close all open dlls and deallocate memory.
280 int close ();
282 /// Find dll in handle_vector_.
283 ACE_DLL_Handle *find_dll (const ACE_TCHAR *dll_name) const;
285 /// Applies strategy for unloading dll.
286 int unload_dll (ACE_DLL_Handle *dll_handle, int force_unload = 0);
288 private:
289 /// Close the singleton instance.
290 static void close_singleton ();
292 ACE_DLL_Manager (const ACE_DLL_Manager &) = delete;
293 void operator= (const ACE_DLL_Manager &) = delete;
294 ACE_DLL_Manager (ACE_DLL_Manager &&) = delete;
295 void operator= (ACE_DLL_Manager &&) = delete;
297 private:
298 /// Vector containing all loaded handle objects.
299 ACE_DLL_Handle **handle_vector_;
301 /// Current number of handles.
302 int current_size_;
304 /// Maximum number of handles.
305 int total_size_;
307 /// Unload strategy.
308 u_long unload_policy_;
310 /// Pointer to a process-wide ACE_DLL_Manager.
311 static ACE_DLL_Manager *instance_;
313 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
314 /// Synchronization variable for the MT_SAFE Repository
315 ACE_Thread_Mutex lock_;
316 #endif /* ACE_MT_SAFE */
319 ACE_END_VERSIONED_NAMESPACE_DECL
321 #include /**/ "ace/post.h"
322 #endif /* ACE_DLL_MANAGER_H */