PortableServer::Servant RequestProcessingStrategyServantActivator::incarnate_servant ( const PortableServer::ObjectId& object_id) { PortableServer::Servant servant = 0; // ATTENTION: Trick locking here, see class header for details Non_Servant_Upcall non_servant_upcall (*this->poa_); ACE_UNUSED_ARG (non_servant_upcall); // @@ // Invocations of incarnate on the servant manager are serialized. // Invocations of etherealize on the servant manager are serialized. // Invocations of incarnate and etherealize on the servant manager are mutually exclusive. servant = this->servant_activator_->incarnate (object_id, this->poa_); if (servant == 0) { throw ::CORBA::OBJ_ADAPTER (CORBA::OMGVMCID | 7, CORBA::COMPLETED_NO); } else { return servant; } }
void RequestProcessingStrategyAOMOnly::cleanup_servant ( PortableServer::Servant servant, const PortableServer::ObjectId &user_id) { if (servant) { // ATTENTION: Trick locking here, see class header for details Non_Servant_Upcall non_servant_upcall (*this->poa_); ACE_UNUSED_ARG (non_servant_upcall); try { servant->_remove_ref (); } catch (...) { // Ignore exceptions from servant cleanup. } } // This operation causes the association of the Object Id specified // by the oid parameter and its servant to be removed from the // Active Object Map. if (this->poa_->unbind_using_user_id (user_id) != 0) { throw ::CORBA::OBJ_ADAPTER (); } }
void RequestProcessingStrategyDefaultServant::set_servant ( PortableServer::Servant servant) { // This operation registers the specified servant with the POA as // the default servant. This servant will be used for all requests // for which no servant is found in the Active Object Map. this->default_servant_ = servant; // The implementation of set_servant will invoke _add_ref at least // once on the Servant argument before returning. When the POA no // longer needs the Servant, it will invoke _remove_ref on it the // same number of times. if (servant != 0) { // A recursive thread lock without using a recursive thread // lock. Non_Servant_Upcall has a magic constructor and // destructor. We unlock the Object_Adapter lock for the // duration of the servant activator upcalls; reacquiring once // the upcalls complete. Even though we are releasing the lock, // other threads will not be able to make progress since // <Object_Adapter::non_servant_upcall_in_progress_> has been // set. Non_Servant_Upcall non_servant_upcall (*this->poa_); ACE_UNUSED_ARG (non_servant_upcall); servant->_add_ref (); } }
PortableServer::ObjectId * ServantRetentionStrategyRetain::activate_object ( PortableServer::Servant servant, CORBA::Short priority, bool &wait_occurred_restart_call) { if (!this->poa_->has_system_id ()) { throw PortableServer::POA::WrongPolicy (); } bool may_activate = this->poa_->is_servant_activation_allowed (servant, wait_occurred_restart_call); if (!may_activate) { if (wait_occurred_restart_call) { return 0; } else { throw PortableServer::POA::ServantAlreadyActive (); } } // Otherwise, the activate_object operation generates an Object Id // and enters the Object Id and the specified servant in the Active // Object Map. The Object Id is returned. PortableServer::ObjectId_var user_id; if (this->active_object_map_-> bind_using_system_id_returning_user_id (servant, priority, user_id.out ()) != 0) { throw ::CORBA::OBJ_ADAPTER (); } // // Everything is finally ok // // Inform the custom servant dispatching (CSD) strategy that the // sevant is activated. this->poa_->servant_activated_hook (servant, user_id.in ()); // ATTENTION: Trick locking here, see class header for details Non_Servant_Upcall non_servant_upcall (*this->poa_); ACE_UNUSED_ARG (non_servant_upcall); // The implementation of activate_object will invoke _add_ref at // least once on the Servant argument before returning. When the POA // no longer needs the Servant, it will invoke _remove_ref on it the // same number of times. servant->_add_ref (); return user_id._retn (); }
void RequestProcessingStrategyServantActivator::strategy_cleanup (void) { { Non_Servant_Upcall non_servant_upcall (*this->poa_); ACE_UNUSED_ARG (non_servant_upcall); this->servant_activator_ = PortableServer::ServantActivator::_nil (); } RequestProcessingStrategy::strategy_cleanup (); }
void RequestProcessingStrategyServantActivator::etherealize_servant ( const PortableServer::ObjectId& object_id, PortableServer::Servant servant, CORBA::Boolean cleanup_in_progress) { CORBA::Boolean const remaining_activations = this->poa_->servant_has_remaining_activations (servant); // ATTENTION: Trick locking here, see class header for details Non_Servant_Upcall non_servant_upcall (*this->poa_); ACE_UNUSED_ARG (non_servant_upcall); // @todo This is not according to the spec. According to 11.3.6.2 at the // end when etherealize returns a system exception the POA ignores the // exception this->servant_activator_->etherealize (object_id, this->poa_, servant, cleanup_in_progress, remaining_activations); }
void ServantRetentionStrategyRetain::activate_object_with_id ( const PortableServer::ObjectId &id, PortableServer::Servant servant, CORBA::Short priority, bool &wait_occurred_restart_call) { // If the POA has the SYSTEM_ID policy and it detects that the // Object Id value was not generated by the system or for this POA, // the activate_object_with_id operation may raise the BAD_PARAM // system exception. An ORB is not required to detect all such // invalid Object Id values, but a portable application must not // invoke activate_object_with_id on a POA that has the SYSTEM_ID // policy with an Object Id value that was not previously generated // by the system for that POA, or, if the POA also has the // PERSISTENT policy, for a previous instantiation of the same POA. if (this->poa_->has_system_id () && !this->poa_->is_poa_generated_id (id)) { throw ::CORBA::BAD_PARAM (); } // If the CORBA object denoted by the Object Id value is already // active in this POA (there is a servant bound to it in the Active // Object Map), the ObjectAlreadyActive exception is raised. bool priorities_match = true; bool result = this->is_user_id_in_map (id, priority, priorities_match, wait_occurred_restart_call); // @johnny the implementation is not complete, this does the spec also say // If the POA has the UNIQUE_ID policy and the servant is already // in the Active Object Map, the ServantAlreadyActive exception is raised. if (result) { throw PortableServer::POA::ObjectAlreadyActive (); } else if (wait_occurred_restart_call) { // We ended up waiting on a condition variable, the POA state // may have changed while we are waiting. Therefore, we need to // restart this call. return; } // If the activate_object_with_id_and_priority operation is invoked // with a different priority to an earlier invocation of one of the // create reference with priority operations, for the same object, // then the ORB shall raise a BAD_INV_ORDER system exception (with a // Standard Minor Exception Code of 1). If the priority value is the // same then the ORB shall return SUCCESS. if (!priorities_match) { throw ::CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 1, CORBA::COMPLETED_NO); } bool const may_activate = this->poa_->is_servant_activation_allowed (servant, wait_occurred_restart_call); if (!may_activate) { if (wait_occurred_restart_call) { return; } else { throw PortableServer::POA::ServantAlreadyActive (); } } // Otherwise, the activate_object_with_id operation enters an // association between the specified Object Id and the specified // servant in the Active Object Map. if (this->active_object_map_->bind_using_user_id (servant, id, priority) != 0) { throw ::CORBA::OBJ_ADAPTER (); } // // Everything is finally ok // // Inform the custom servant dispatching (CSD) strategy that the // sevant is activated. this->poa_->servant_activated_hook (servant, id); // ATTENTION: Trick locking here, see class header for details Non_Servant_Upcall non_servant_upcall (*this->poa_); ACE_UNUSED_ARG (non_servant_upcall); // The implementation of activate_object_with_id will invoke // _add_ref at least once on the Servant argument before // returning. When the POA no longer needs the Servant, it will // invoke _remove_ref on it the same number of times. servant->_add_ref (); }
PortableServer::ObjectId * ServantRetentionStrategyRetain::servant_to_system_id_i ( PortableServer::Servant servant, CORBA::Short &priority) { // This operation requires the RETAIN and either the UNIQUE_ID or // IMPLICIT_ACTIVATION policies; if not present, the WrongPolicy // exception is raised. if (!((!this->poa_->allow_multiple_activations () || this->poa_->allow_implicit_activation ()))) { throw PortableServer::POA::WrongPolicy (); } // This operation has three possible behaviors. // If the POA has the UNIQUE_ID policy and the specified servant is // active, the Object Id associated with that servant is returned. PortableServer::ObjectId_var system_id; if (!this->poa_->allow_multiple_activations () && this->active_object_map_-> find_system_id_using_servant (servant, system_id.out (), priority) != -1) { return system_id._retn (); } #if defined (CORBA_E_COMPACT) || defined (CORBA_E_MICRO) // CORBA e does not allow implicit activation. // At this point we can throw the WrongPolicy exception. throw PortableServer::POA::WrongPolicy (); #endif /* CORBA_E_COMPACT || CORBA_E_MICRO */ // If the POA has the IMPLICIT_ACTIVATION policy and either the POA // has the MULTIPLE_ID policy or the specified servant is not // active, the servant is activated using a POA-generated Object Id // and the Interface Id associated with the servant, and that Object // Id is returned. if (this->poa_->allow_implicit_activation ()) { // If we reach here, then we either have the MULTIPLE_ID policy // or we have the UNIQUE_ID policy and we are not in the active // object map. PortableServer::ObjectId_var system_id; if (this->active_object_map_-> bind_using_system_id_returning_system_id (servant, priority, system_id.out ()) != 0) { throw ::CORBA::OBJ_ADAPTER (); } // // Everything is finally ok // // Inform the custom servant dispatching (CSD) strategy that the // sevant is activated. this->poa_->servant_activated_hook (servant, system_id.in ()); // ATTENTION: Trick locking here, see class header for details Non_Servant_Upcall non_servant_upcall (*this->poa_); ACE_UNUSED_ARG (non_servant_upcall); // If this operation causes the object to be activated, _add_ref // is invoked at least once on the Servant argument before // returning. Otherwise, the POA does not increment or decrement // the reference count of the Servant passed to this function. servant->_add_ref (); return system_id._retn (); } // Otherwise, the ServantNotActive exception is raised. throw PortableServer::POA::ServantNotActive (); }
void RequestProcessingStrategyServantActivator::cleanup_servant ( PortableServer::Servant servant, const PortableServer::ObjectId &user_id ) { // If a servant manager is associated with the POA, // ServantLocator::etherealize will be invoked with the oid and the // servant. (The deactivate_object operation does not wait for the // etherealize operation to complete before deactivate_object // returns.) // // Note: If the servant associated with the oid is serving multiple // Object Ids, ServantLocator::etherealize may be invoked multiple // times with the same servant when the other objects are // deactivated. It is the responsibility of the object // implementation to refrain from destroying the servant while it is // active with any Id. // If the POA has no ServantActivator associated with it, the POA // implementation calls _remove_ref when all operation invocations // have completed. If there is a ServantActivator, the Servant is // consumed by the call to ServantActivator::etherealize instead. // @bala, is this order correct, see 11.3.9.17 of the spec, it // says first remove from the map, then etherealize. not the // other way around // @@ Johnny, you are right! This will not show up until a // thread is trying to activate the object in another thread // using activate_object_with_id (). A test case is a must for // atleast this issue. if (servant) { if (this->etherealize_objects_ && !CORBA::is_nil (this->servant_activator_.in ())) { this->etherealize_servant (user_id, servant, this->poa_->cleanup_in_progress ()); } else { // ATTENTION: Trick locking here, see class header for details Non_Servant_Upcall non_servant_upcall (*this->poa_); ACE_UNUSED_ARG (non_servant_upcall); try { servant->_remove_ref (); } catch (...) { // Ignore exceptions from servant cleanup. } } } // This operation causes the association of the Object Id specified // by the oid parameter and its servant to be removed from the // Active Object Map. if (this->poa_->unbind_using_user_id (user_id) != 0) throw ::CORBA::OBJ_ADAPTER (); }
void ImR_Client_Adapter_Impl::imr_notify_shutdown (TAO_Root_POA* poa ) { // Notify the Implementation Repository about shutting down. CORBA::Object_var imr = poa->orb_core ().implrepo_service (); // Check to see if there was an imr returned. // If none, return ourselves. if (CORBA::is_nil (imr.in ())) return; try { if (TAO_debug_level > 0) { CORBA::String_var poaname = poa->the_name (); TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO_ImR_Client (%P|%t) - Notifying IMR of Shutdown server: <%C>\n"), poaname.in ())); } // ATTENTION: Trick locking here, see class header for details TAO::Portable_Server::Non_Servant_Upcall non_servant_upcall (*poa); ACE_UNUSED_ARG (non_servant_upcall); // Get the IMR's administrative object and call shutting_down on it ImplementationRepository::Administration_var imr_locator = ImplementationRepository::Administration::_narrow (imr.in ()); imr_locator->server_is_shutting_down (poa->name ().c_str ()); } catch (const ::CORBA::COMM_FAILURE&) { // At the moment we call this during ORB shutdown and the ORB is // configured to drop replies during shutdown (it does by default in // the LF model) we get a COMM_FAILURE exception which we ignore if (TAO_debug_level > 0) { TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO_ImR_Client (%P|%t) - Ignoring COMM_FAILURE while unregistering") ACE_TEXT ("from ImR.\n"))); } } catch (const ::CORBA::TRANSIENT&) { // Similarly, there are cases where we could get a TRANSIENT. if (TAO_debug_level > 0) { TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO_ImR_Client (%P|%t) - Ignoring TRANSIENT while unregistering") ACE_TEXT ("from ImR.\n"))); } } catch (const ::CORBA::Exception& ex) { ex._tao_print_exception ( "ImR_Client_Adapter_Impl::imr_notify_shutdown()"); // Ignore exceptions } if (this->server_object_) { PortableServer::POA_var default_poa = this->server_object_->_default_POA (); TAO_Root_POA *root_poa = dynamic_cast <TAO_Root_POA*> (default_poa.in ()); if (!root_poa) { throw ::CORBA::OBJ_ADAPTER (); } PortableServer::ObjectId_var id = root_poa->servant_to_id_i (this->server_object_); root_poa->deactivate_object_i (id.in ()); this->server_object_ = 0; } }
void ImR_Client_Adapter_Impl::imr_notify_startup (TAO_Root_POA* poa ) { CORBA::Object_var imr = poa->orb_core ().implrepo_service (); if (CORBA::is_nil (imr.in ())) { if (TAO_debug_level > 0) { TAOLIB_ERROR ((LM_ERROR, ACE_TEXT ("TAO_ImR_Client (%P|%t) - ERROR: No usable IMR initial reference ") ACE_TEXT ("available but use IMR has been specified.\n"))); } throw ::CORBA::TRANSIENT ( CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE, 0), CORBA::COMPLETED_NO); } if (TAO_debug_level > 0) { if (TAO_debug_level > 1) { CORBA::ORB_ptr orb = poa->orb_core ().orb (); CORBA::String_var ior = orb->object_to_string (imr.in ()); TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO_ImR_Client (%P|%t) - Notifying ImR of startup IMR IOR <%C>\n"), ior.in ())); } } ImplementationRepository::Administration_var imr_locator; { // ATTENTION: Trick locking here, see class header for details TAO::Portable_Server::Non_Servant_Upcall non_servant_upcall (*poa); ACE_UNUSED_ARG (non_servant_upcall); imr_locator = ImplementationRepository::Administration::_narrow (imr.in ()); } if (CORBA::is_nil (imr_locator.in ())) { if (TAO_debug_level > 0) { TAOLIB_ERROR ((LM_ERROR, ACE_TEXT ("TAO_ImR_Client (%P|%t) - ERROR: Narrowed IMR initial reference ") ACE_TEXT ("is nil but use IMR has been specified.\n"))); } throw ::CORBA::TRANSIENT ( CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE, 0), CORBA::COMPLETED_NO); } TAO_Root_POA *root_poa = poa->object_adapter ().root_poa (); ACE_NEW_THROW_EX (this->server_object_, ServerObject_i (poa->orb_core ().orb (), root_poa), CORBA::NO_MEMORY ()); PortableServer::ServantBase_var safe_servant (this->server_object_); ACE_UNUSED_ARG (safe_servant); // Since this method is called from the POA constructor, there // shouldn't be any waiting required. Therefore, // <wait_occurred_restart_call_ignored> can be ignored. bool wait_occurred_restart_call_ignored = false; // Activate the servant in the root poa. PortableServer::ObjectId_var id = root_poa->activate_object_i (this->server_object_, poa->server_priority (), wait_occurred_restart_call_ignored); CORBA::Object_var obj = root_poa->id_to_reference_i (id.in (), false); ImplementationRepository::ServerObject_var svr = ImplementationRepository::ServerObject::_narrow (obj.in ()); if (!svr->_stubobj () || !svr->_stubobj ()->profile_in_use ()) { if (TAO_debug_level > 0) { TAOLIB_ERROR ((LM_ERROR, "TAO_ImR_Client (%P|%t) - Invalid ImR ServerObject, bailing out.\n")); } return; } CORBA::ORB_var orb = root_poa->_get_orb (); CORBA::String_var full_ior = orb->object_to_string (obj.in ()); TAO_Profile& profile = *(svr->_stubobj ()->profile_in_use ()); CORBA::String_var ior = profile.to_string(); if (TAO_debug_level > 0) { TAOLIB_DEBUG((LM_INFO, "TAO_ImR_Client (%P|%t) - full_ior <%C>\nior <%C>\n", full_ior.in(), ior.in())); } char* const pos = find_delimiter (ior.inout (), profile.object_key_delimiter ()); const ACE_CString partial_ior (ior.in (), (pos - ior.in ()) + 1); if (TAO_debug_level > 0) { CORBA::String_var poaname = poa->the_name (); TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO_ImR_Client (%P|%t) - Informing IMR that <%C> is running at <%C>\n"), poaname.in(), partial_ior.c_str ())); } try { // ATTENTION: Trick locking here, see class header for details TAO::Portable_Server::Non_Servant_Upcall non_servant_upcall (*poa); ACE_UNUSED_ARG (non_servant_upcall); ACE_CString const serverId = poa->orb_core ().server_id (); ACE_CString name; if (serverId.empty ()) { name = poa->name (); } else { name = serverId + ":" + poa->name (); } imr_locator->server_is_running (name.c_str (), partial_ior.c_str (), svr.in ()); } catch (const ::CORBA::SystemException&) { throw; } catch (const ::CORBA::Exception&) { throw ::CORBA::TRANSIENT ( CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE, 0), CORBA::COMPLETED_NO); } if (TAO_debug_level > 0) { TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO_ImR_Client (%P|%t) - Successfully notified ImR of Startup\n"))); } }