int ACE_Service_Repository::fini (void) { ACE_TRACE ("ACE_Service_Repository::fini"); ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); if (this->service_vector_ == 0) return 0; int retval = 0; // Do not be tempted to use the prefix decrement operator. Use // postfix decrement operator since the index is unsigned and may // wrap around the 0 for (size_t i = this->current_size_; i-- != 0;) { // <fini> the services in reverse order. ACE_Service_Type *s = const_cast<ACE_Service_Type *> (this->service_vector_[i]); #ifndef ACE_NLOGGING if (ACE::debug ()) { if (s != 0) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] (%d), ") ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"), this, i, this->total_size_, s->name(), s->type (), (s->type () != 0) ? s->type ()->object () : 0, s->active ())); else ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] (%d) -> 0\n"), this, i, this->total_size_)); } #endif // Collect any errors. if (s != 0) retval += s->fini (); } return (retval == 0) ? 0 : -1; }
int ACE_Service_Gestalt::initialize (const ACE_Service_Type_Factory *stf, const ACE_TCHAR *parameters) { ACE_TRACE ("ACE_Service_Gestalt::initialize"); #ifndef ACE_NLOGGING if (ACE::debug ()) ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE (%P|%t) SG::initialize - repo=%@, name=%s") ACE_TEXT (" - looking up in the repo\n"), this->repo_, stf->name ())); #endif ACE_Service_Type *srp = 0; int const retv = this->repo_->find (stf->name (), (const ACE_Service_Type **) &srp); // If there is an active service already, remove it first // before it can be re-installed. if (retv >= 0) { #ifndef ACE_NLOGGING if (ACE::debug ()) ACELIB_DEBUG ((LM_WARNING, ACE_TEXT ("ACE (%P|%t) SG::initialize - repo=%@,") ACE_TEXT (" name=%s - removing a pre-existing namesake.\n"), this->repo_, stf->name ())); #endif this->repo_->remove (stf->name ()); } // If there is an inactive service by that name it may have been // either inactivated, or just a forward declaration for a service, // that is in the process of being initialized. If it is the latter, // then we have detected an attempt to initialize the same dynamic // service while still processing previous attempt. This can lock up // the process, because the ACE_DLL_Manager::open () is not // re-entrant - it uses a Singleton lock to serialize concurent // invocations. This use case must be handled here, because if the // DLL_Manager was re-entrant we would have entered an infinite // recursion here. if (retv == -2 && srp->type () == 0) ACELIB_ERROR_RETURN ((LM_WARNING, ACE_TEXT ("ACE (%P|%t) SG::initialize - repo=%@,") ACE_TEXT (" name=%s - forward-declared; ") ACE_TEXT (" recursive initialization requests are") ACE_TEXT (" ignored.\n"), this->repo_, stf->name ()), -1); // Reserve a spot for the dynamic service by inserting an incomplete // service declaration, i.e. one that can not produce a service // object if asked (a forward declaration). This declaration // ensures maintaining the proper partial ordering of the services // with respect to their finalization. For example, dependent static // services must be registered *after* the dynamic service that // loads them, so that their finalization is complete *before* // finalizing the dynamic service. ACE_Service_Type_Dynamic_Guard dummy (*this->repo_, stf->name ()); // make_service_type() is doing the dynamic loading and also runs // any static initializers ACE_Auto_Ptr<ACE_Service_Type> tmp (stf->make_service_type (this)); if (tmp.get () != 0 && this->initialize_i (tmp.get (), parameters) == 0) { // All good. Tthe ACE_Service_Type instance is now owned by the // repository and we should make sure it is not destroyed upon // exit from this method. tmp.release (); return 0; } return -1; }
int ACE_Service_Repository::fini (void) { ACE_TRACE ("ACE_Service_Repository::fini"); ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); int retval = 0; // Do not be tempted to use the prefix decrement operator. Use // postfix decrement operator since the index is unsigned and may // wrap around the 0 // // debug output for empty service entries #ifndef ACE_NLOGGING if (ACE::debug ()) { for (size_t i = this->service_array_.size (); i-- != 0;) { ACE_Service_Type *s = const_cast<ACE_Service_Type *> (this->service_array_[i]); if (s == 0) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] -> 0\n"), this, i)); } } #endif // // Remove all the Service_Object and Stream instances // for (size_t i = this->service_array_.size (); i-- != 0;) { // <fini> the services in reverse order. ACE_Service_Type *s = const_cast<ACE_Service_Type *> (this->service_array_[i]); if (s != 0 && s->type () != 0 && (s->type ()->service_type () != ACE_Service_Type::MODULE)) { #ifndef ACE_NLOGGING if (ACE::debug ()) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d], ") ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"), this, i, s->name (), s->type (), (s->type () != 0) ? s->type ()->object () : 0, s->active ())); } #endif // Collect any errors. retval += s->fini (); } } // // Remove all the Module instances // for (size_t i = this->service_array_.size (); i-- != 0;) { // <fini> the services in reverse order. ACE_Service_Type *s = const_cast<ACE_Service_Type *> (this->service_array_[i]); if (s != 0 && s->type () != 0 && (s->type ()->service_type () == ACE_Service_Type::MODULE)) { #ifndef ACE_NLOGGING if (ACE::debug ()) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d], ") ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"), this, i, s->name (), s->type (), (s->type () != 0) ? s->type ()->object () : 0, s->active ())); } #endif // Collect any errors. retval += s->fini (); } } return (retval == 0) ? 0 : -1; }