Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / DLL.cpp
blobb5880d09d0c30659aa61323932f57fbbdabfa8c4
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>
12 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
14 // Default constructor. Also, by default, the object will be closed
15 // before it is destroyed.
17 ACE_DLL::ACE_DLL (bool close_handle_on_destruction)
18 : open_mode_ (0),
19 dll_name_ (0),
20 close_handle_on_destruction_ (close_handle_on_destruction),
21 dll_handle_ (0),
22 error_ (0)
24 ACE_TRACE ("ACE_DLL::ACE_DLL (int)");
27 ACE_DLL::ACE_DLL (const ACE_DLL &rhs)
28 : open_mode_ (0),
29 dll_name_ (0),
30 close_handle_on_destruction_ (false),
31 dll_handle_ (0),
32 error_ (0)
34 ACE_TRACE ("ACE_DLL::ACE_DLL (const ACE_DLL &)");
36 if (rhs.dll_name_
37 // This will automatically up the refcount.
38 && this->open (rhs.dll_name_,
39 rhs.open_mode_,
40 rhs.close_handle_on_destruction_) != 0
41 && ACE::debug ())
42 ACELIB_ERROR ((LM_ERROR,
43 ACE_TEXT ("ACE_DLL::copy_ctor: error: %s\n"),
44 this->error ()));
47 // Assignment operator
49 ACE_DLL &
50 ACE_DLL::operator= (const ACE_DLL &rhs)
52 ACE_TRACE ("ACE_DLL::operator= (const ACE_DLL &)");
54 ACE_DLL tmp (rhs);
56 std::swap (this->open_mode_, tmp.open_mode_);
57 std::swap (this->dll_name_, tmp.dll_name_);
58 std::swap (this->close_handle_on_destruction_,
59 tmp.close_handle_on_destruction_);
60 std::swap (this->dll_handle_, tmp.dll_handle_);
61 std::swap (this->error_, tmp.error_);
63 return *this;
67 // If the library name and the opening mode are specified than on
68 // object creation the library is implicitly opened.
70 ACE_DLL::ACE_DLL (const ACE_TCHAR *dll_name,
71 int open_mode,
72 bool close_handle_on_destruction)
73 : open_mode_ (open_mode),
74 dll_name_ (0),
75 close_handle_on_destruction_ (close_handle_on_destruction),
76 dll_handle_ (0),
77 error_ (0)
79 ACE_TRACE ("ACE_DLL::ACE_DLL");
81 if (this->open (dll_name, this->open_mode_, close_handle_on_destruction) != 0
82 && ACE::debug ())
83 ACELIB_ERROR ((LM_ERROR,
84 ACE_TEXT ("ACE_DLL::open: error calling open: %s\n"),
85 this->error ()));
88 // The library is closed before the class gets destroyed depending on
89 // the close_handle_on_destruction value specified which is stored in
90 // close_handle_on_destruction_.
92 ACE_DLL::~ACE_DLL ()
94 ACE_TRACE ("ACE_DLL::~ACE_DLL");
96 this->close ();
98 // Normally delete()d in ACE_DLL::close(). However, that may not
99 // occur if full ACE_DLL initialization is interrupted due to errors
100 // (e.g. attempting to open a DSO/DLL that does not exist). Make
101 // sure this->dll_name_ is deallocated.
102 #if defined (ACE_HAS_ALLOC_HOOKS)
103 ACE_Allocator::instance()->free (this->dll_name_);
104 #else
105 delete [] this->dll_name_;
106 #endif /* ACE_HAS_ALLOC_HOOKS */
109 // This method opens the library based on the mode specified using the
110 // ACE_SHLIB_HANDLE which is obtained on making the ACE_OS::dlopen call.
111 // The default mode is:
112 // RTLD_LAZY Only references to data symbols are relocate when the
113 // object is first loaded.
114 // The other modes include:
115 // RTLD_NOW All necessary relocations are performed when the
116 // object is first loaded.
117 // RTLD_GLOBAL The object symbols are made available for the
118 // relocation processing of any other object.
121 ACE_DLL::open (const ACE_TCHAR *dll_filename,
122 int open_mode,
123 bool close_handle_on_destruction)
125 ACE_TRACE ("ACE_DLL::open");
127 return open_i (dll_filename, open_mode, close_handle_on_destruction);
131 ACE_DLL::open_i (const ACE_TCHAR *dll_filename,
132 int open_mode,
133 bool close_handle_on_destruction,
134 ACE_SHLIB_HANDLE handle)
136 ACE_TRACE ("ACE_DLL::open_i");
138 this->error_ = 0;
139 this->errmsg_.clear (true);
141 if (!dll_filename)
143 if (ACE::debug ())
144 ACELIB_ERROR ((LM_ERROR,
145 ACE_TEXT ("ACE_DLL::open_i: dll_name is %s\n"),
146 this->dll_name_ == 0 ? ACE_TEXT ("(null)")
147 : this->dll_name_));
148 return -1;
151 if (this->dll_handle_)
153 // If we have a good handle and its the same name, just return.
154 if (ACE_OS::strcmp (this->dll_name_, dll_filename) == 0)
155 return 0;
156 else
157 this->close ();
160 if (!this->dll_name_)
161 this->dll_name_ = ACE::strnew (dll_filename);
163 this->open_mode_ = open_mode;
164 this->close_handle_on_destruction_ = close_handle_on_destruction;
166 ACE_DLL_Handle::ERROR_STACK errors;
167 this->dll_handle_ = ACE_DLL_Manager::instance()->open_dll (this->dll_name_,
168 this->open_mode_,
169 handle,
170 &errors);
172 if (!this->dll_handle_)
174 ACE_TString errtmp;
175 while (!errors.is_empty ())
177 errors.pop (errtmp);
178 if (this->errmsg_.length () > 0)
179 this->errmsg_ += ACE_TEXT ("\n");
180 this->errmsg_ += errtmp;
182 this->error_ = 1;
185 return this->error_ ? -1 : 0;
188 // The symbol refernce of the name specified is obtained.
190 void *
191 ACE_DLL::symbol (const ACE_TCHAR *sym_name, int ignore_errors)
193 ACE_TRACE ("ACE_DLL::symbol");
195 this->error_ = 0;
196 this->errmsg_.clear (true);
198 void *sym = 0;
199 if (this->dll_handle_)
200 sym = this->dll_handle_->symbol (sym_name, ignore_errors, this->errmsg_);
202 if (!sym)
203 this->error_ = 1;
205 return sym;
208 // The library is closed using the ACE_SHLIB_HANDLE object, i.e., the
209 // shared object is now disassociated form the current process.
212 ACE_DLL::close ()
214 ACE_TRACE ("ACE_DLL::close");
216 int retval = 0;
218 if (this->dll_handle_
219 && this->close_handle_on_destruction_
220 && this->dll_name_
221 && (retval = ACE_DLL_Manager::instance ()->close_dll (this->dll_name_)) != 0)
222 this->error_ = 1;
224 // Even if close_dll() failed, go ahead and cleanup.
225 this->dll_handle_ = 0;
226 #if defined (ACE_HAS_ALLOC_HOOKS)
227 ACE_Allocator::instance()->free (this->dll_name_);
228 #else
229 delete [] this->dll_name_;
230 #endif /* ACE_HAS_ALLOC_HOOKS */
231 this->dll_name_ = 0;
232 this->close_handle_on_destruction_ = false;
234 return retval;
237 // This method is used return the last error of a library operation.
239 ACE_TCHAR *
240 ACE_DLL::error () const
242 ACE_TRACE ("ACE_DLL::error");
243 if (this->error_)
245 return const_cast<ACE_TCHAR*> (this->errmsg_.c_str ());
248 return 0;
251 // Return the handle to the user either temporarily or forever, thus
252 // orphaning it. If 0 means the user wants the handle forever and if 1
253 // means the user temporarily wants to take the handle.
255 ACE_SHLIB_HANDLE
256 ACE_DLL::get_handle (bool become_owner) const
258 ACE_TRACE ("ACE_DLL::get_handle");
260 ACE_SHLIB_HANDLE handle = ACE_SHLIB_INVALID_HANDLE;
262 if (this->dll_handle_)
263 handle = this->dll_handle_->get_handle (become_owner);
265 return handle;
268 // Set the handle for the DLL. By default, the object will be closed
269 // before it is destroyed.
272 ACE_DLL::set_handle (ACE_SHLIB_HANDLE handle,
273 bool close_handle_on_destruction)
275 ACE_TRACE ("ACE_DLL::set_handle");
277 // Create a unique name. Note that this name is only guaranteed
278 // to be unique for the life of this object.
279 ACE_TCHAR temp[ACE_UNIQUE_NAME_LEN];
280 ACE_OS::unique_name (this, temp, ACE_UNIQUE_NAME_LEN);
282 return this->open_i (temp, 1, close_handle_on_destruction, handle);
285 ACE_END_VERSIONED_NAMESPACE_DECL