Also use Objects as part of an operation but as a result don't generate Any operation...
[ACE_TAO.git] / ACE / ace / DLL.cpp
blob998a52a8827d85be6149363bb4dbf97e97a8f440
1 #include "ace/DLL.h"
3 #include "ace/Log_Category.h"
4 #include "ace/ACE.h"
5 #include "ace/DLL_Manager.h"
6 #include "ace/OS_NS_string.h"
7 #include "ace/OS_NS_dlfcn.h"
8 #include "ace/OS_NS_Thread.h"
10 #include <algorithm>
14 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
16 // Default constructor. Also, by default, the object will be closed
17 // before it is destroyed.
19 ACE_DLL::ACE_DLL (bool close_handle_on_destruction)
20 : open_mode_ (0),
21 dll_name_ (0),
22 close_handle_on_destruction_ (close_handle_on_destruction),
23 dll_handle_ (0),
24 error_ (0)
26 ACE_TRACE ("ACE_DLL::ACE_DLL (int)");
29 ACE_DLL::ACE_DLL (const ACE_DLL &rhs)
30 : open_mode_ (0),
31 dll_name_ (0),
32 close_handle_on_destruction_ (false),
33 dll_handle_ (0),
34 error_ (0)
36 ACE_TRACE ("ACE_DLL::ACE_DLL (const ACE_DLL &)");
38 if (rhs.dll_name_
39 // This will automatically up the refcount.
40 && this->open (rhs.dll_name_,
41 rhs.open_mode_,
42 rhs.close_handle_on_destruction_) != 0
43 && ACE::debug ())
44 ACELIB_ERROR ((LM_ERROR,
45 ACE_TEXT ("ACE_DLL::copy_ctor: error: %s\n"),
46 this->error ()));
49 // Assignment operator
51 ACE_DLL &
52 ACE_DLL::operator= (const ACE_DLL &rhs)
54 ACE_TRACE ("ACE_DLL::operator= (const ACE_DLL &)");
56 ACE_DLL tmp (rhs);
58 std::swap (this->open_mode_, tmp.open_mode_);
59 std::swap (this->dll_name_, tmp.dll_name_);
60 std::swap (this->close_handle_on_destruction_,
61 tmp.close_handle_on_destruction_);
62 std::swap (this->dll_handle_, tmp.dll_handle_);
63 std::swap (this->error_, tmp.error_);
65 return *this;
69 // If the library name and the opening mode are specified than on
70 // object creation the library is implicitly opened.
72 ACE_DLL::ACE_DLL (const ACE_TCHAR *dll_name,
73 int open_mode,
74 bool close_handle_on_destruction)
75 : open_mode_ (open_mode),
76 dll_name_ (0),
77 close_handle_on_destruction_ (close_handle_on_destruction),
78 dll_handle_ (0),
79 error_ (0)
81 ACE_TRACE ("ACE_DLL::ACE_DLL");
83 if (this->open (dll_name, this->open_mode_, close_handle_on_destruction) != 0
84 && ACE::debug ())
85 ACELIB_ERROR ((LM_ERROR,
86 ACE_TEXT ("ACE_DLL::open: error calling open: %s\n"),
87 this->error ()));
90 // The library is closed before the class gets destroyed depending on
91 // the close_handle_on_destruction value specified which is stored in
92 // close_handle_on_destruction_.
94 ACE_DLL::~ACE_DLL (void)
96 ACE_TRACE ("ACE_DLL::~ACE_DLL");
98 this->close ();
100 // Normally delete()d in ACE_DLL::close(). However, that may not
101 // occur if full ACE_DLL initialization is interrupted due to errors
102 // (e.g. attempting to open a DSO/DLL that does not exist). Make
103 // sure this->dll_name_ is deallocated.
104 #if defined (ACE_HAS_ALLOC_HOOKS)
105 ACE_Allocator::instance()->free (this->dll_name_);
106 #else
107 delete [] this->dll_name_;
108 #endif /* ACE_HAS_ALLOC_HOOKS */
111 // This method opens the library based on the mode specified using the
112 // ACE_SHLIB_HANDLE which is obtained on making the ACE_OS::dlopen call.
113 // The default mode is:
114 // RTLD_LAZY Only references to data symbols are relocate when the
115 // object is first loaded.
116 // The other modes include:
117 // RTLD_NOW All necessary relocations are performed when the
118 // object is first loaded.
119 // RTLD_GLOBAL The object symbols are made available for the
120 // relocation processing of any other object.
123 ACE_DLL::open (const ACE_TCHAR *dll_filename,
124 int open_mode,
125 bool close_handle_on_destruction)
127 ACE_TRACE ("ACE_DLL::open");
129 return open_i (dll_filename, open_mode, close_handle_on_destruction);
133 ACE_DLL::open_i (const ACE_TCHAR *dll_filename,
134 int open_mode,
135 bool close_handle_on_destruction,
136 ACE_SHLIB_HANDLE handle)
138 ACE_TRACE ("ACE_DLL::open_i");
140 this->error_ = 0;
141 this->errmsg_.clear (true);
143 if (!dll_filename)
145 if (ACE::debug ())
146 ACELIB_ERROR ((LM_ERROR,
147 ACE_TEXT ("ACE_DLL::open_i: dll_name is %s\n"),
148 this->dll_name_ == 0 ? ACE_TEXT ("(null)")
149 : this->dll_name_));
150 return -1;
153 if (this->dll_handle_)
155 // If we have a good handle and its the same name, just return.
156 if (ACE_OS::strcmp (this->dll_name_, dll_filename) == 0)
157 return 0;
158 else
159 this->close ();
162 if (!this->dll_name_)
163 this->dll_name_ = ACE::strnew (dll_filename);
165 this->open_mode_ = open_mode;
166 this->close_handle_on_destruction_ = close_handle_on_destruction;
168 ACE_DLL_Handle::ERROR_STACK errors;
169 this->dll_handle_ = ACE_DLL_Manager::instance()->open_dll (this->dll_name_,
170 this->open_mode_,
171 handle,
172 &errors);
174 if (!this->dll_handle_)
176 ACE_TString errtmp;
177 while (!errors.is_empty ())
179 errors.pop (errtmp);
180 if (this->errmsg_.length () > 0)
181 this->errmsg_ += ACE_TEXT ("\n");
182 this->errmsg_ += errtmp;
184 this->error_ = 1;
187 return this->error_ ? -1 : 0;
190 // The symbol refernce of the name specified is obtained.
192 void *
193 ACE_DLL::symbol (const ACE_TCHAR *sym_name, int ignore_errors)
195 ACE_TRACE ("ACE_DLL::symbol");
197 this->error_ = 0;
198 this->errmsg_.clear (true);
200 void *sym = 0;
201 if (this->dll_handle_)
202 sym = this->dll_handle_->symbol (sym_name, ignore_errors, this->errmsg_);
204 if (!sym)
205 this->error_ = 1;
207 return sym;
210 // The library is closed using the ACE_SHLIB_HANDLE object, i.e., the
211 // shared object is now disassociated form the current process.
214 ACE_DLL::close (void)
216 ACE_TRACE ("ACE_DLL::close");
218 int retval = 0;
220 if (this->dll_handle_
221 && this->close_handle_on_destruction_
222 && this->dll_name_
223 && (retval = ACE_DLL_Manager::instance ()->close_dll (this->dll_name_)) != 0)
224 this->error_ = 1;
226 // Even if close_dll() failed, go ahead and cleanup.
227 this->dll_handle_ = 0;
228 #if defined (ACE_HAS_ALLOC_HOOKS)
229 ACE_Allocator::instance()->free (this->dll_name_);
230 #else
231 delete [] this->dll_name_;
232 #endif /* ACE_HAS_ALLOC_HOOKS */
233 this->dll_name_ = 0;
234 this->close_handle_on_destruction_ = false;
236 return retval;
239 // This method is used return the last error of a library operation.
241 ACE_TCHAR *
242 ACE_DLL::error (void) const
244 ACE_TRACE ("ACE_DLL::error");
245 if (this->error_)
247 return const_cast<ACE_TCHAR*> (this->errmsg_.c_str ());
250 return 0;
253 // Return the handle to the user either temporarily or forever, thus
254 // orphaning it. If 0 means the user wants the handle forever and if 1
255 // means the user temporarily wants to take the handle.
257 ACE_SHLIB_HANDLE
258 ACE_DLL::get_handle (bool become_owner) const
260 ACE_TRACE ("ACE_DLL::get_handle");
262 ACE_SHLIB_HANDLE handle = ACE_SHLIB_INVALID_HANDLE;
264 if (this->dll_handle_)
265 handle = this->dll_handle_->get_handle (become_owner);
267 return handle;
270 // Set the handle for the DLL. By default, the object will be closed
271 // before it is destroyed.
274 ACE_DLL::set_handle (ACE_SHLIB_HANDLE handle,
275 bool close_handle_on_destruction)
277 ACE_TRACE ("ACE_DLL::set_handle");
279 // Create a unique name. Note that this name is only guaranteed
280 // to be unique for the life of this object.
281 ACE_TCHAR temp[ACE_UNIQUE_NAME_LEN];
282 ACE_OS::unique_name (this, temp, ACE_UNIQUE_NAME_LEN);
284 return this->open_i (temp, 1, close_handle_on_destruction, handle);
287 ACE_END_VERSIONED_NAMESPACE_DECL