#include <Service_Gestalt.h>
Collaboration diagram for ACE_Service_Type_Dynamic_Guard:
Public Member Functions | |
ACE_Service_Type_Dynamic_Guard (ACE_Service_Repository &r, ACE_TCHAR const *name) | |
~ACE_Service_Type_Dynamic_Guard (void) | |
Destructor. | |
Private Attributes | |
ACE_Service_Repository & | repo_ |
size_t | repo_begin_ |
ACE_TCHAR const *const | name_ |
Helps to resolve an issue with hybrid services, i.e. dynamic services, accompanied by static services in the same DLL. Only automatic instances of this class are supposed to exist. Those are created during (dynamic) service initialization and serve to:
(a) Ensure the service we are loading is ordered last in the repository, following any other services it may cause to register, as part of its own registration. This is a common case when loading dynamic services from DLLs - there are often static initializers, which register static services.
(b) The SDG instance destructor detects if the dynamic service initialized successfully and "fixes-up" all the newly registered static services to hold a reference to the DLL, from which they have originated.
Definition at line 481 of file Service_Gestalt.h.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_Service_Type_Dynamic_Guard::ACE_Service_Type_Dynamic_Guard | ( | ACE_Service_Repository & | r, | |
ACE_TCHAR const * | name | |||
) |
Definition at line 39 of file Service_Gestalt.cpp.
References ACE_ASSERT, ACE_DEBUG, ACE_TEXT, ACE::debug(), and LM_DEBUG.
00040 : repo_ (r) 00041 // Relocation starts where the next service will be inserted (if any) 00042 , repo_begin_ (r.current_size ()) 00043 , name_ (name) 00044 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) 00045 // On this thread (for the duration of the initialize() method), 00046 // we're about to do two things that require locking: (1) fiddle 00047 // with the repository and (2) load a DLL and hence lock the 00048 // DLL_Manager. 00049 // 00050 // Now if we don't lock the repo here, it is possible that two 00051 // threads may deadlock on initialization because they can acquire 00052 // locks (1) and (2) in different order, for instance: 00053 // 00054 // T1: loads a DLL (2) and registers a service (1); 00055 // 00056 // T2: may be relocating a service (1), which could lead to a 00057 // (re)opening or uping the ref count on a DLL (2); 00058 // 00059 // To prevent this, we lock the repo here, using the repo_monitor_ 00060 // member guard. 00061 , repo_monitor_ (r.lock_) 00062 #endif 00063 { 00064 if (ACE::debug ()) 00065 ACE_DEBUG ((LM_DEBUG, 00066 ACE_TEXT ("ACE (%P|%t) STDG::<ctor>, repo=%@") 00067 ACE_TEXT(", name=%s - begining at [%d]\n"), 00068 &this->repo_, 00069 this->name_, 00070 this->repo_begin_)); 00071 00072 ACE_ASSERT (this->name_ != 0); // No name? 00073 }
ACE_Service_Type_Dynamic_Guard::~ACE_Service_Type_Dynamic_Guard | ( | void | ) |
Destructor.
Definition at line 78 of file Service_Gestalt.cpp.
References ACE_DEBUG, ACE_ERROR, ACE_TEXT, ACE_Service_Type::active(), ACE::debug(), ACE_Service_Type::dll(), ACE_Service_Repository::find_i(), LM_DEBUG, LM_WARNING, ACE_Service_Type_Impl::object(), ACE_Service_Repository::relocate_i(), repo_, and ACE_Service_Type::type().
00079 { 00080 const ACE_Service_Type *tmp = 0; 00081 00082 // Lookup without ignoring suspended services. Making sure 00083 // not to ignore any inactive services, since those may be forward 00084 // declarations 00085 size_t slot = 0; 00086 int const ret = this->repo_.find_i (this->name_, slot, &tmp, false); 00087 00088 // We inserted it (as inactive), so we expect to find it, right? 00089 if ((ret < 0 && ret != -2) || tmp == 0) 00090 { 00091 if (ACE::debug ()) 00092 ACE_ERROR ((LM_WARNING, 00093 ACE_TEXT ("ACE (%P|%t) STDG::<dtor> - Failed (%d) to find %s -> %@\n"), 00094 ret, this->name_, tmp)); 00095 return; 00096 } 00097 00098 if (tmp->type () != 0) 00099 { 00100 // Something has registered a proper (non-forward-decl) service with 00101 // the same name as our dummy. 00102 00103 if (ACE::debug ()) 00104 ACE_DEBUG ((LM_DEBUG, 00105 ACE_TEXT ("ACE (%P|%t) STDG::<dtor>, repo=%@ [%d], ") 00106 ACE_TEXT ("name=%s - updating dependents [%d - %d)\n"), 00107 &this->repo_, 00108 slot, 00109 this->name_, 00110 this->repo_begin_, 00111 this->repo_.current_size ())); 00112 00113 // Relocate any services inserted since we were created. 00114 // Any (static, i.e. DLL = 0) services registered in 00115 // the context of this guard aren't really static because 00116 // their code belongs in the DLL's code segment 00117 this->repo_.relocate_i (this->repo_begin_, this->repo_.current_size (), tmp->dll()); 00118 00119 if (ACE::debug ()) 00120 ACE_DEBUG ((LM_DEBUG, 00121 ACE_TEXT ("ACE (%P|%t) STDG::<dtor>, repo=%@ [%d], ") 00122 ACE_TEXT ("name=%s - loaded (type=%@, impl=%@, object=%@, active=%d)\n"), 00123 &this->repo_, 00124 slot, 00125 this->name_, 00126 tmp, 00127 tmp->type (), 00128 tmp->type ()->object (), 00129 tmp->active ())); 00130 } 00131 }
ACE_TCHAR const* const ACE_Service_Type_Dynamic_Guard::name_ [private] |
Definition at line 492 of file Service_Gestalt.h.
size_t ACE_Service_Type_Dynamic_Guard::repo_begin_ [private] |
Definition at line 491 of file Service_Gestalt.h.