00001
00002
00003 #include "ace/DLL_Manager.h"
00004
00005 #include "ace/Log_Msg.h"
00006 #include "ace/ACE.h"
00007 #include "ace/Framework_Component.h"
00008
00009 #include "ace/Lib_Find.h"
00010 #include "ace/Object_Manager.h"
00011 #include "ace/SString.h"
00012 #include "ace/Recursive_Thread_Mutex.h"
00013 #include "ace/Guard_T.h"
00014 #include "ace/OS_NS_dlfcn.h"
00015 #include "ace/OS_NS_string.h"
00016
00017 ACE_RCSID (ace,
00018 DLL_Manager,
00019 "DLL_Manager.cpp,v 4.23 2003/11/05 23:30:46 shuston Exp")
00020
00021
00022
00023 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00024
00025 sig_atomic_t ACE_DLL_Handle::open_called_ = 0;
00026
00027 ACE_DLL_Handle::ACE_DLL_Handle (void)
00028 : refcount_ (0),
00029 dll_name_ (0),
00030 handle_ (ACE_SHLIB_INVALID_HANDLE)
00031 {
00032 ACE_TRACE ("ACE_DLL_Handle::ACE_DLL_Handle");
00033 }
00034
00035 ACE_DLL_Handle::~ACE_DLL_Handle (void)
00036 {
00037 ACE_TRACE ("ACE_DLL_Handle::~ACE_DLL_Handle");
00038 this->close (1);
00039 delete[] this->dll_name_;
00040 }
00041
00042 const ACE_TCHAR *
00043 ACE_DLL_Handle::dll_name (void) const
00044 {
00045 ACE_TRACE ("ACE_DLL_Handle::dll_name");
00046 return this->dll_name_;
00047 }
00048
00049 int
00050 ACE_DLL_Handle::open (const ACE_TCHAR *dll_name,
00051 int open_mode,
00052 ACE_SHLIB_HANDLE handle)
00053 {
00054 ACE_TRACE ("ACE_DLL_Handle::open");
00055 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00056
00057 if (this->dll_name_)
00058 {
00059
00060 if (ACE_OS::strcmp (this->dll_name_, dll_name) != 0)
00061 {
00062 if (ACE::debug ())
00063 ACE_ERROR ((LM_ERROR,
00064 ACE_TEXT ("ACE (%P|%t) DLL_Handle::open: error, ")
00065 ACE_TEXT ("tried to reopen %s with name %s\n"),
00066 this->dll_name_,
00067 dll_name));
00068
00069 return -1;
00070 }
00071 }
00072 else
00073 this->dll_name_ = ACE::strnew (dll_name);
00074
00075 if (!this->open_called_)
00076 this->open_called_ = 1;
00077
00078
00079 if (this->handle_ == ACE_SHLIB_INVALID_HANDLE)
00080 {
00081 if (handle)
00082 this->handle_ = handle;
00083 else
00084 {
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 ACE_Array<ACE_TString> dll_names;
00102 dll_names.max_size (10);
00103
00104 #if defined (ACE_MUST_HELP_DLOPEN_SEARCH_PATH)
00105
00106 ACE_TCHAR dll_pathname[MAXPATHLEN + 1];
00107
00108
00109
00110 ACE::ldfind (dll_name,
00111 dll_pathname,
00112 (sizeof dll_pathname / sizeof (ACE_TCHAR)));
00113 ACE_TString dll_str (dll_pathname);
00114 dll_names.size (1);
00115 dll_names.set (dll_str, 0);
00116 #else
00117 this->get_dll_names (dll_name, dll_names);
00118 #endif
00119
00120 ACE_Array_Iterator<ACE_TString> name_iter (dll_names);
00121 ACE_TString *name = 0;
00122 while (name_iter.next (name))
00123 {
00124
00125 this->handle_ = ACE_OS::dlopen (name->c_str (),
00126 open_mode);
00127
00128 if (ACE::debug ())
00129 {
00130 ACE_DEBUG ((LM_DEBUG,
00131 ACE_TEXT ("ACE (%P|%t) DLL_Handle::open ")
00132 ACE_TEXT ("(\"%s\", 0x%x) -> %s: %s\n"),
00133 name->c_str (),
00134 open_mode,
00135 ((this->handle_ != ACE_SHLIB_INVALID_HANDLE)
00136 ? ACE_TEXT ("succeeded")
00137 : ACE_TEXT ("failed")),
00138 this->error()->c_str()));
00139 }
00140
00141 if (this->handle_ != ACE_SHLIB_INVALID_HANDLE)
00142 break;
00143
00144
00145
00146
00147
00148
00149
00150 if ((errno != 0) && (errno != ENOENT) && ACE::debug ())
00151 ACE_ERROR ((LM_ERROR,
00152 ACE_TEXT ("ACE (%P|%t) DLL_Handle::open ")
00153 ACE_TEXT ("(\'%s\') failed, errno=")
00154 ACE_TEXT ("%d: <%s>\n"),
00155 name->c_str (),
00156 ACE_ERRNO_GET,
00157 this->error ()->c_str ()));
00158
00159 #if defined (AIX)
00160
00161
00162
00163 if (ACE_TString::npos != name->strstr (ACE_TEXT (".a")))
00164 {
00165 ACE_TCHAR aix_pathname[MAXPATHLEN + 1];
00166 ACE_OS::strncpy (aix_pathname,
00167 name->c_str (),
00168 name->length ());
00169 aix_pathname[name->length ()] = '\0';
00170 ACE_OS::strcat (aix_pathname, ACE_TEXT ("(shr.o)"));
00171 open_mode |= RTLD_MEMBER;
00172
00173 if (ACE::debug ())
00174 {
00175 ACE_DEBUG ((LM_DEBUG,
00176 ACE_TEXT ("ACE (%P|%t) DLL_Handle::open ")
00177 ACE_TEXT ("(\"%s\", 0x%x) -> %s: %s\n"),
00178 aix_pathname,
00179 open_mode,
00180 (this->handle_ != ACE_SHLIB_INVALID_HANDLE
00181 ? ACE_TEXT ("succeeded")
00182 : ACE_TEXT ("failed")),
00183 this->error()->c_str()));
00184 }
00185
00186 this->handle_ = ACE_OS::dlopen (aix_pathname, open_mode);
00187 if (this->handle_ != ACE_SHLIB_INVALID_HANDLE)
00188 break;
00189
00190
00191
00192
00193
00194
00195
00196 if (ACE::debug () && (errno != 0) && (errno != ENOENT))
00197 ACE_ERROR ((LM_ERROR,
00198 ACE_TEXT ("ACE (%P|%t) DLL_Handle::open ")
00199 ACE_TEXT ("(\'%s\') failed, errno=")
00200 ACE_TEXT ("%d: %s\n"),
00201 name->c_str (),
00202 errno,
00203 this->error ()->c_str ()));
00204
00205 }
00206 #endif
00207
00208 name_iter.advance ();
00209 }
00210
00211 if (this->handle_ == ACE_SHLIB_INVALID_HANDLE)
00212 {
00213 if (ACE::debug ())
00214 ACE_ERROR ((LM_ERROR,
00215 ACE_TEXT ("ACE (%P|%t) DLL_Handle::open (\"%s\"): ")
00216 ACE_TEXT ("Invalid handle error: %s\n"),
00217 this->dll_name_,
00218 this->error ()->c_str ()));
00219
00220 return -1;
00221 }
00222 }
00223 }
00224
00225 ++this->refcount_;
00226
00227 if (ACE::debug ())
00228 ACE_DEBUG ((LM_DEBUG,
00229 ACE_TEXT ("ACE (%P|%t) DLL_Handle::open - %s (%d), refcount=%d\n"),
00230 this->dll_name_,
00231 this->handle_,
00232 this->refcount_));
00233 return 0;
00234 }
00235
00236
00237 int
00238 ACE_DLL_Handle::close (int unload)
00239 {
00240 ACE_TRACE ("ACE_DLL_Handle::close");
00241
00242 int retval = 0;
00243 ACE_SHLIB_HANDLE h = ACE_SHLIB_INVALID_HANDLE;
00244
00245
00246
00247
00248 {
00249 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00250
00251
00252
00253
00254 if (this->refcount_ > 0)
00255 --this->refcount_;
00256 else
00257 this->refcount_ = 0;
00258
00259 if (ACE::debug ())
00260 ACE_DEBUG ((LM_DEBUG,
00261 ACE_TEXT ("ACE (%P|%t) DLL_Handle::close - ")
00262 ACE_TEXT ("%s (handle=%d, refcount=%d)\n"),
00263 this->dll_name_,
00264 this->handle_,
00265 this->refcount_));
00266
00267 if (this->refcount_ == 0 &&
00268 this->handle_ != ACE_SHLIB_INVALID_HANDLE &&
00269 unload == 1)
00270 {
00271 if (ACE::debug ())
00272 ACE_DEBUG ((LM_DEBUG,
00273 ACE_TEXT ("ACE (%P|%t) DLL_Handle::close: ")
00274 ACE_TEXT ("Unloading %s (handle=%d)\n"),
00275 this->dll_name_,
00276 this->handle_));
00277
00278
00279 ACE_Framework_Repository *frPtr= ACE_Framework_Repository::instance ();
00280 if (frPtr)
00281 {
00282 frPtr->remove_dll_components (this->dll_name_);
00283 }
00284
00285 h = this->handle_;
00286 this->handle_ = ACE_SHLIB_INVALID_HANDLE;
00287 }
00288 }
00289
00290 if (h != ACE_SHLIB_INVALID_HANDLE)
00291 {
00292 retval = ACE_OS::dlclose (h);
00293
00294 if (retval != 0 && ACE::debug ())
00295 ACE_ERROR ((LM_ERROR,
00296 ACE_TEXT ("ACE (%P|%t) DLL_Handle::close - ")
00297 ACE_TEXT ("Failed with: \"%s\".\n"),
00298 this->error ()->c_str ()));
00299 }
00300
00301 return retval;
00302 }
00303
00304 sig_atomic_t
00305 ACE_DLL_Handle::refcount (void) const
00306 {
00307 return this->refcount_;
00308 }
00309
00310 void *
00311 ACE_DLL_Handle::symbol (const ACE_TCHAR *sym_name, int ignore_errors)
00312 {
00313 ACE_TRACE ("ACE_DLL_Handle::symbol");
00314 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00315
00316 ACE_Auto_Array_Ptr <ACE_TCHAR> auto_name (ACE::ldname (sym_name));
00317
00318
00319 if (this->handle_ != ACE_SHLIB_INVALID_HANDLE)
00320 {
00321 #if defined (ACE_OPENVMS)
00322 void *sym = ACE::ldsymbol (this->handle_, auto_name.get ());
00323 #else
00324 void *sym = ACE_OS::dlsym (this->handle_, auto_name.get ());
00325 #endif
00326
00327
00328
00329
00330
00331 if (!sym && ignore_errors != 1)
00332 {
00333 if (ACE::debug ())
00334 ACE_ERROR ((LM_ERROR,
00335 ACE_TEXT ("ACE (%P|%t) DLL_Handle::symbol (\"%s\") ")
00336 ACE_TEXT (" failed with \"%s\".\n"),
00337 auto_name.get (),
00338 this->error ()->c_str ()));
00339
00340 return 0;
00341 }
00342 return sym;
00343 }
00344 return 0;
00345 }
00346
00347 ACE_SHLIB_HANDLE
00348 ACE_DLL_Handle::get_handle (int become_owner)
00349 {
00350 ACE_TRACE ("ACE_DLL_Handle::get_handle");
00351 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00352
00353 if (this->refcount_ == 0 && become_owner != 0)
00354 {
00355 if (ACE::debug ())
00356 ACE_ERROR ((LM_ERROR,
00357 ACE_TEXT ("ACE (%P|%t) DLL_Handle::get_handle: ")
00358 ACE_TEXT ("cannot become owner, refcount == 0.\n")));
00359
00360 return ACE_SHLIB_INVALID_HANDLE;
00361 }
00362
00363 ACE_SHLIB_HANDLE handle = this->handle_;
00364
00365 if (become_owner != 0)
00366 {
00367 if (--this->refcount_ == 0)
00368 this->handle_ = ACE_SHLIB_INVALID_HANDLE;
00369 }
00370
00371 if (ACE::debug ())
00372 ACE_DEBUG ((LM_DEBUG,
00373 ACE_TEXT ("ACE (%P|%t) DLL_Handle::get_handle: ")
00374 ACE_TEXT ("post call: handle %s, refcount %d\n"),
00375 this->handle_ == ACE_SHLIB_INVALID_HANDLE ?
00376 ACE_TEXT ("invalid") : ACE_TEXT ("valid"),
00377 this->refcount_));
00378
00379 return handle;
00380 }
00381
00382
00383
00384 auto_ptr <ACE_TString>
00385 ACE_DLL_Handle::error (void)
00386 {
00387 ACE_TRACE ("ACE_DLL_Handle::error");
00388 const ACE_TCHAR *error = ACE_OS::dlerror ();
00389 auto_ptr<ACE_TString> str
00390 (new ACE_TString (error ? error : ACE_TEXT ("no error")));
00391 return str;
00392 }
00393
00394 void
00395 ACE_DLL_Handle::get_dll_names (const ACE_TCHAR *dll_name,
00396 ACE_Array<ACE_TString> &try_names)
00397 {
00398
00399
00400 ACE_TString base (dll_name);
00401 ACE_TString base_dir, base_file, base_suffix;
00402
00403
00404
00405 ACE_TString::size_type pos = base.rfind (ACE_DIRECTORY_SEPARATOR_CHAR);
00406 if (pos != ACE_TString::npos)
00407 {
00408 base_dir = base.substr (0, pos + 1);
00409 base_file = base.substr (pos + 1);
00410 }
00411 else
00412 base_file = base;
00413
00414
00415
00416 if ((pos = base_file.rfind (ACE_TEXT ('.'))) != ACE_TString::npos)
00417 {
00418 base_suffix = base_file.substr (pos);
00419 base_file = base_file.substr (0, pos);
00420 }
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 try_names.size (0);
00438 if ((try_names.max_size () - try_names.size ()) < 5)
00439 try_names.max_size (try_names.max_size () + 5);
00440 #if defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00441 ACE_TString decorator (ACE_LD_DECORATOR_STR);
00442 #endif
00443 ACE_TString suffix (ACE_DLL_SUFFIX);
00444 ACE_TString prefix (ACE_DLL_PREFIX);
00445
00446 for (size_t i = 0; i < 5 && try_names.size () < try_names.max_size (); ++i)
00447 {
00448 ACE_TString try_this;
00449 size_t const j = try_names.size ();
00450 switch (i)
00451 {
00452 case 0:
00453 case 1:
00454 case 2:
00455 case 3:
00456 if (
00457 base_suffix.length () > 0
00458 #if !(defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK))
00459 || (i == 1 || i == 3)
00460 #endif
00461 )
00462 break;
00463 try_this = base_dir;
00464 if (i > 1)
00465 try_this += prefix;
00466 try_this += base_file;
00467 if (base_suffix.length () > 0)
00468 try_this += base_suffix;
00469 else
00470 {
00471 #if defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00472 try_this += decorator;
00473 #endif
00474 try_this += suffix;
00475 }
00476 break;
00477 case 4:
00478 try_this = dll_name;
00479 break;
00480 }
00481
00482 if (try_this.length ())
00483 {
00484 try_names.size (j + 1);
00485 try_names.set (try_this, j);
00486 }
00487 }
00488 return;
00489 }
00490
00491
00492
00493
00494 ACE_DLL_Manager *ACE_DLL_Manager::instance_ = 0;
00495
00496
00497 ACE_DLL_Manager *
00498 ACE_DLL_Manager::instance (int size)
00499 {
00500 ACE_TRACE ("ACE_DLL_Manager::instance");
00501
00502 if (ACE_DLL_Manager::instance_ == 0)
00503 {
00504
00505 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00506 *ACE_Static_Object_Lock::instance (), 0));
00507 if (ACE_DLL_Manager::instance_ == 0)
00508 {
00509 ACE_NEW_RETURN (ACE_DLL_Manager::instance_,
00510 ACE_DLL_Manager (size),
00511 0);
00512 }
00513 }
00514
00515 return ACE_DLL_Manager::instance_;
00516 }
00517
00518 void
00519 ACE_DLL_Manager::close_singleton (void)
00520 {
00521 ACE_TRACE ("ACE_DLL_Manager::close_singleton");
00522
00523 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00524 *ACE_Static_Object_Lock::instance ()));
00525
00526 delete ACE_DLL_Manager::instance_;
00527 ACE_DLL_Manager::instance_ = 0;
00528 }
00529
00530 ACE_DLL_Manager::ACE_DLL_Manager (int size)
00531 : handle_vector_ (0),
00532 current_size_ (0),
00533 total_size_ (0),
00534 unload_policy_ (ACE_DLL_UNLOAD_POLICY_PER_DLL)
00535 {
00536 ACE_TRACE ("ACE_DLL_Manager::ACE_DLL_Manager");
00537
00538 if (this->open (size) != 0 && ACE::debug ())
00539 ACE_ERROR ((LM_ERROR,
00540 ACE_TEXT ("ACE (%P|%t) DLL_Manager ctor failed to allocate ")
00541 ACE_TEXT ("handle_vector_.\n")));
00542 }
00543
00544 ACE_DLL_Manager::~ACE_DLL_Manager (void)
00545 {
00546 ACE_TRACE ("ACE_DLL_Manager::~ACE_DLL_Manager");
00547
00548 if (this->close () != 0 && ACE::debug ())
00549 ACE_ERROR ((LM_ERROR,
00550 ACE_TEXT ("ACE (%P|%t) DLL_Manager dtor failed to close ")
00551 ACE_TEXT ("properly.\n")));
00552 }
00553
00554 ACE_DLL_Handle *
00555 ACE_DLL_Manager::open_dll (const ACE_TCHAR *dll_name,
00556 int open_mode,
00557 ACE_SHLIB_HANDLE handle)
00558 {
00559 ACE_TRACE ("ACE_DLL_Manager::open_dll");
00560
00561 ACE_DLL_Handle *temp_handle = 0;
00562 ACE_DLL_Handle *dll_handle = 0;
00563 {
00564 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00565 dll_handle = this->find_dll (dll_name);
00566 if (!dll_handle)
00567 {
00568 if (this->current_size_ < this->total_size_)
00569 {
00570 ACE_NEW_RETURN (temp_handle,
00571 ACE_DLL_Handle,
00572 0);
00573
00574 dll_handle = temp_handle;
00575 }
00576 }
00577 }
00578
00579 if (dll_handle)
00580 {
00581 if (dll_handle->open (dll_name, open_mode, handle) != 0)
00582 {
00583
00584 if (ACE::debug ())
00585 ACE_ERROR ((LM_ERROR,
00586 ACE_TEXT ("ACE (%P|%t) DLL_Manager::open_dll: Could not ")
00587 ACE_TEXT ("open dll %s.\n"),
00588 dll_name));
00589
00590 delete temp_handle;
00591 return 0;
00592 }
00593
00594
00595
00596 if (temp_handle != 0)
00597 {
00598 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00599 this->handle_vector_[this->current_size_] = dll_handle;
00600 ++this->current_size_;
00601 }
00602 }
00603
00604 return dll_handle;
00605 }
00606
00607 int
00608 ACE_DLL_Manager::close_dll (const ACE_TCHAR *dll_name)
00609 {
00610 ACE_TRACE ("ACE_DLL_Manager::close_dll");
00611 ACE_DLL_Handle *handle = 0;
00612
00613 {
00614 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00615 handle = this->find_dll (dll_name);
00616 }
00617
00618 if (handle)
00619 {
00620 return this->unload_dll (handle, 0);
00621 }
00622
00623 return -1;
00624 }
00625
00626 u_long
00627 ACE_DLL_Manager::unload_policy (void) const
00628 {
00629 ACE_TRACE ("ACE_DLL_Manager::unload_policy");
00630 return this->unload_policy_;
00631 }
00632
00633 void
00634 ACE_DLL_Manager::unload_policy (u_long unload_policy)
00635 {
00636 ACE_TRACE ("ACE_DLL_Manager::unload_policy");
00637 ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->lock_));
00638
00639 u_long old_policy = this->unload_policy_;
00640 this->unload_policy_ = unload_policy;
00641
00642
00643
00644
00645 if (this->handle_vector_)
00646 if (( ACE_BIT_ENABLED (old_policy, ACE_DLL_UNLOAD_POLICY_LAZY) &&
00647 ACE_BIT_DISABLED (this->unload_policy_, ACE_DLL_UNLOAD_POLICY_LAZY) ) ||
00648 ( ACE_BIT_DISABLED (this->unload_policy_, ACE_DLL_UNLOAD_POLICY_LAZY) &&
00649 ACE_BIT_ENABLED (old_policy, ACE_DLL_UNLOAD_POLICY_PER_DLL) &&
00650 ACE_BIT_DISABLED (this->unload_policy_, ACE_DLL_UNLOAD_POLICY_PER_DLL) ))
00651 {
00652 for (int i = this->current_size_ - 1; i >= 0; i--)
00653 {
00654 if (this->handle_vector_[i] &&
00655 this->handle_vector_[i]->refcount () == 0)
00656 this->handle_vector_[i]->close (1);
00657 }
00658 }
00659 }
00660
00661 int
00662 ACE_DLL_Manager::open (int size)
00663 {
00664 ACE_TRACE ("ACE_DLL_Manager::open");
00665
00666 ACE_DLL_Handle **temp = 0;
00667
00668 ACE_NEW_RETURN (temp,
00669 ACE_DLL_Handle *[size],
00670 -1);
00671
00672 this->handle_vector_ = temp;
00673 this->total_size_ = size;
00674 return 0;
00675 }
00676
00677 int
00678 ACE_DLL_Manager::close (void)
00679 {
00680 ACE_TRACE ("ACE_DLL_Manager::close");
00681
00682 int force_close = 1;
00683
00684 if (this->handle_vector_ != 0)
00685 {
00686
00687 for (int i = this->current_size_ - 1; i >= 0; i--)
00688 {
00689 if (this->handle_vector_[i])
00690 {
00691 ACE_DLL_Handle *s =
00692 const_cast<ACE_DLL_Handle *> (this->handle_vector_[i]);
00693 this->handle_vector_[i] = 0;
00694 this->unload_dll (s, force_close);
00695 delete s;
00696 }
00697 }
00698
00699 delete [] this->handle_vector_;
00700 this->handle_vector_ = 0;
00701 this->current_size_ = 0;
00702 }
00703 return 0;
00704 }
00705
00706 ACE_DLL_Handle *
00707 ACE_DLL_Manager::find_dll (const ACE_TCHAR *dll_name) const
00708 {
00709 ACE_TRACE ("ACE_DLL_Manager::find_dll");
00710
00711 for (int i = 0; i < this->current_size_; i++)
00712 if (this->handle_vector_[i] &&
00713 ACE_OS::strcmp (this->handle_vector_[i]->dll_name (), dll_name) == 0)
00714 {
00715 return this->handle_vector_[i];
00716 }
00717
00718 return 0;
00719 }
00720
00721 int
00722 ACE_DLL_Manager::unload_dll (ACE_DLL_Handle *dll_handle, int force_unload)
00723 {
00724 ACE_TRACE ("ACE_DLL_Manager::unload_dll");
00725
00726 if (dll_handle)
00727 {
00728 int unload = force_unload;
00729 if (unload == 0)
00730 {
00731
00732 if (ACE_BIT_DISABLED (this->unload_policy_,
00733 ACE_DLL_UNLOAD_POLICY_PER_DLL))
00734 {
00735 unload = ACE_BIT_DISABLED (this->unload_policy_,
00736 ACE_DLL_UNLOAD_POLICY_LAZY);
00737 }
00738 else
00739 {
00740
00741 typedef int (*dll_unload_policy)(void);
00742
00743 void * const unload_policy_ptr =
00744 dll_handle->symbol (ACE_TEXT ("_get_dll_unload_policy"), 1);
00745 #if defined (ACE_OPENVMS) && (!defined (__INITIAL_POINTER_SIZE) || (__INITIAL_POINTER_SIZE < 64))
00746 int const temp_p =
00747 reinterpret_cast<int> (unload_policy_ptr);
00748 #else
00749 intptr_t const temp_p =
00750 reinterpret_cast<intptr_t> (unload_policy_ptr);
00751 #endif
00752
00753 dll_unload_policy const the_policy =
00754 reinterpret_cast<dll_unload_policy> (temp_p);
00755
00756 if (the_policy != 0)
00757 unload = ACE_BIT_DISABLED (the_policy (),
00758 ACE_DLL_UNLOAD_POLICY_LAZY);
00759 else
00760 unload = ACE_BIT_DISABLED (this->unload_policy_,
00761 ACE_DLL_UNLOAD_POLICY_LAZY);
00762 }
00763 }
00764
00765 if (dll_handle->close (unload) != 0)
00766 {
00767 if (ACE::debug ())
00768 ACE_ERROR ((LM_ERROR,
00769 ACE_TEXT ("ACE (%P|%t) DLL_Manager::unload error.\n")));
00770
00771 return -1;
00772 }
00773 }
00774 else
00775 {
00776 if (ACE::debug ())
00777 ACE_ERROR ((LM_ERROR,
00778 ACE_TEXT ("ACE (%P|%t) DLL_Manager::unload_dll called with ")
00779 ACE_TEXT ("null pointer.\n")));
00780
00781 return -1;
00782 }
00783
00784 return 0;
00785 }
00786
00787 ACE_END_VERSIONED_NAMESPACE_DECL