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::Servant ServantLocatorImpl::preinvoke( const PortableServer::ObjectId& oid, PortableServer::POA_ptr poa, const char* operation, PortableServer::ServantLocator::Cookie& cookie) { printf("------- ServantLocator.preinvoke(.., op='%s', .. ) " "--------\n", operation); PortableServer::Servant servant = _servant_array[(_round_robin_idx++)%5].in(); servant->_add_ref(); return servant; }
void GCServantLocator::register_servant(const PortableServer::ObjectId& oid, PortableServer::Servant servant, boost::posix_time::time_duration ttl, const std::string& destroy) { boost::mutex::scoped_lock lock(activeMapMutex_); if (activeMap_.count(oid) > 0) { throw PortableServer::POA::ObjectAlreadyActive(); } LOG_TRACE(GCServantLocator, "tracking " << (void*)servant); ServantEntry& entry = activeMap_[oid]; entry.servant = servant; servant->_add_ref(); entry.ttl = ttl; entry.last_access = boost::get_system_time(); entry.destroy = destroy; }
PortableServer::Servant GCServantLocator::preinvoke(const PortableServer::ObjectId& oid, PortableServer::POA_ptr adapter, const char* operation, PortableServer::ServantLocator::Cookie& the_cookie) { boost::mutex::scoped_lock lock(activeMapMutex_); ServantMap::iterator iter = activeMap_.find(oid); if (iter == activeMap_.end()) { throw CORBA::OBJECT_NOT_EXIST(); } PortableServer::Servant servant = iter->second.servant; if (iter->second.destroy == std::string(operation)) { LOG_TRACE(GCServantLocator, "untracking " << (void*)servant); activeMap_.erase(iter); } else { servant->_add_ref(); iter->second.last_access = boost::get_system_time(); } return servant; }
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 (); }