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 ();
}
Ejemplo n.º 10
0
    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;
        }
    }
Ejemplo n.º 11
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")));
        }
    }