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 ();
        }
    }
Exemple #2
0
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 ();
    }