Classes | Public Types | Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions | Friends

TAO::Portable_Server::Servant_Upcall Class Reference

This class finds out the POA and the servant to perform an upcall. It can only be instantiated without the object adapter's lock held. For each upcall a new instance of this class is created. More...

#include <Servant_Upcall.h>

Collaboration diagram for TAO::Portable_Server::Servant_Upcall:
Collaboration graph
[legend]

List of all members.

Classes

class  Pre_Invoke_State
 This struct keeps track of state related to pre- and post-invoke operations. More...

Public Types

enum  State {
  INITIAL_STAGE, OBJECT_ADAPTER_LOCK_ACQUIRED, POA_CURRENT_SETUP, OBJECT_ADAPTER_LOCK_RELEASED,
  SERVANT_LOCK_ACQUIRED
}

Public Member Functions

 Servant_Upcall (TAO_ORB_Core *orb_core)
 Constructor.
 ~Servant_Upcall (void)
 Destructor.
int prepare_for_upcall (const TAO::ObjectKey &key, const char *operation, CORBA::Object_out forward_to)
 Locate POA and servant.
int prepare_for_upcall_i (const TAO::ObjectKey &key, const char *operation, CORBA::Object_out forward_to, bool &wait_occurred_restart_call)
 Helper.
void pre_invoke_remote_request (TAO_ServerRequest &req)
 Run pre_invoke for a remote request.
void pre_invoke_collocated_request (void)
 Run pre_invoke for a collocated request.
void post_invoke (void)
 Run post_invoke for a request.
::TAO_Root_POAlookup_POA (const TAO::ObjectKey &key)
 Locate POA.
::TAO_Root_POApoa (void) const
 POA accessor.
TAO_Object_Adapterobject_adapter (void) const
 Object Adapter accessor.
const PortableServer::ObjectIdid (void) const
 System ID accessor.
void user_id (const PortableServer::ObjectId *)
const PortableServer::ObjectIduser_id (void) const
PortableServer::Servant servant (void) const
 Servant accessor.
void * locator_cookie (void) const
 Get the Servant Locator's cookie.
void locator_cookie (void *cookie)
 Set the Servant Locator's cookie.
const char * operation (void) const
 Get the operation name.
void operation (const char *)
 Set the operation name.
void active_object_map_entry (TAO_Active_Object_Map_Entry *entry)
 Set the active_object_map_entry.
TAO_Active_Object_Map_Entryactive_object_map_entry (void) const
 Get the active_object_map_entry.
CORBA::Short priority (void) const
 Get the priority for the current upcall.
State state (void) const
 Get the state.
void state (State)
 Set the state.
void increment_servant_refcount (void)
 Increment the refcount.

Protected Member Functions

void post_invoke_servant_cleanup (void)
void single_threaded_poa_setup (void)
void single_threaded_poa_cleanup (void)
void servant_cleanup (void)
void poa_cleanup (void)
void upcall_cleanup (void)
 Clean-up / reset state of this Servant_Upcall object.

Protected Attributes

TAO_Object_Adapterobject_adapter_
::TAO_Root_POApoa_
PortableServer::Servant servant_
State state_
CORBA::Octet system_id_buf_ [TAO_POA_OBJECT_ID_BUF_SIZE]
PortableServer::ObjectId system_id_
const PortableServer::ObjectIduser_id_
POA_Current_Impl current_context_
void * cookie_
 Servant Locator's cookie.
const char * operation_
 Operation name for this current.
TAO_Active_Object_Map_Entryactive_object_map_entry_
Pre_Invoke_State pre_invoke_state_
 Preinvoke data for the upcall.

Private Member Functions

 Servant_Upcall (const Servant_Upcall &)
void operator= (const Servant_Upcall &)

Friends

class ::TAO_RT_Collocation_Resolver

Detailed Description

This class finds out the POA and the servant to perform an upcall. It can only be instantiated without the object adapter's lock held. For each upcall a new instance of this class is created.

Definition at line 60 of file Servant_Upcall.h.


Member Enumeration Documentation

enum TAO::Portable_Server::Servant_Upcall::State
Enumerator:
INITIAL_STAGE 
OBJECT_ADAPTER_LOCK_ACQUIRED 
POA_CURRENT_SETUP 
OBJECT_ADAPTER_LOCK_RELEASED 
SERVANT_LOCK_ACQUIRED 

Definition at line 165 of file Servant_Upcall.h.

      {
        INITIAL_STAGE,
        OBJECT_ADAPTER_LOCK_ACQUIRED,
        POA_CURRENT_SETUP,
        OBJECT_ADAPTER_LOCK_RELEASED,
        SERVANT_LOCK_ACQUIRED
      };


Constructor & Destructor Documentation

TAO::Portable_Server::Servant_Upcall::Servant_Upcall ( TAO_ORB_Core orb_core  )  [explicit]

Constructor.

Definition at line 32 of file Servant_Upcall.cpp.

      : object_adapter_ (0),
        poa_ (0),
        servant_ (0),
        state_ (INITIAL_STAGE),
        system_id_ (TAO_POA_OBJECT_ID_BUF_SIZE, 0, system_id_buf_),
        user_id_ (0),
        current_context_ (),
#if (TAO_HAS_MINIMUM_POA == 0)
        cookie_ (0),
        operation_ (0),
#endif /* TAO_HAS_MINIMUM_POA == 0 */
        active_object_map_entry_ (0)
    {
      TAO_Object_Adapter *object_adapter =
        dynamic_cast<TAO_Object_Adapter *>(oc->poa_adapter ());
      this->object_adapter_ = object_adapter;
    }

TAO::Portable_Server::Servant_Upcall::~Servant_Upcall ( void   ) 

Destructor.

Definition at line 234 of file Servant_Upcall.cpp.

    {
      this->upcall_cleanup ();
    }

TAO::Portable_Server::Servant_Upcall::Servant_Upcall ( const Servant_Upcall  )  [private]

Member Function Documentation

void TAO::Portable_Server::Servant_Upcall::active_object_map_entry ( TAO_Active_Object_Map_Entry entry  ) 

Set the active_object_map_entry.

Definition at line 77 of file Servant_Upcall.inl.

    {
      this->active_object_map_entry_ = entry;
    }

TAO_Active_Object_Map_Entry * TAO::Portable_Server::Servant_Upcall::active_object_map_entry ( void   )  const

Get the active_object_map_entry.

Definition at line 83 of file Servant_Upcall.inl.

    {
      return this->active_object_map_entry_;
    }

const PortableServer::ObjectId & TAO::Portable_Server::Servant_Upcall::id ( void   )  const

System ID accessor.

Definition at line 30 of file Servant_Upcall.inl.

    {
      return this->system_id_;
    }

void TAO::Portable_Server::Servant_Upcall::increment_servant_refcount ( void   ) 

Increment the refcount.

Definition at line 337 of file Servant_Upcall.cpp.

    {
      // Cleanup servant related stuff.
      if (this->active_object_map_entry_ != 0)
        ++this->active_object_map_entry_->reference_count_;
    }

void * TAO::Portable_Server::Servant_Upcall::locator_cookie ( void   )  const

Get the Servant Locator's cookie.

Definition at line 51 of file Servant_Upcall.inl.

    {
      return this->cookie_;
    }

void TAO::Portable_Server::Servant_Upcall::locator_cookie ( void *  cookie  ) 

Set the Servant Locator's cookie.

Definition at line 57 of file Servant_Upcall.inl.

    {
      this->cookie_ = cookie;
    }

TAO_Root_POA * TAO::Portable_Server::Servant_Upcall::lookup_POA ( const TAO::ObjectKey &  key  ) 

Locate POA.

Definition at line 212 of file Servant_Upcall.cpp.

    {
      // Acquire the object adapter lock first.
      if (this->object_adapter_->lock ().acquire () == -1)
        // Locking error.
        throw ::CORBA::OBJ_ADAPTER ();

      // We have acquired the object adapter lock.  Record this for later
      // use.
      this->state_ = OBJECT_ADAPTER_LOCK_ACQUIRED;

      // Check if a non-servant upcall is in progress.  If a non-servant
      // upcall is in progress, wait for it to complete.  Unless of
      // course, the thread making the non-servant upcall is this thread.
      this->object_adapter_->wait_for_non_servant_upcalls_to_complete ();

      // Locate the POA.
      this->object_adapter_->locate_poa (key, this->system_id_, this->poa_);

      return this->poa_;
    }

TAO_Object_Adapter & TAO::Portable_Server::Servant_Upcall::object_adapter ( void   )  const

Object Adapter accessor.

Definition at line 24 of file Servant_Upcall.inl.

    {
      return *this->object_adapter_;
    }

void TAO::Portable_Server::Servant_Upcall::operation ( const char *  name  ) 

Set the operation name.

Definition at line 69 of file Servant_Upcall.inl.

    {
      this->operation_ = name;
    }

const char * TAO::Portable_Server::Servant_Upcall::operation ( void   )  const

Get the operation name.

Definition at line 63 of file Servant_Upcall.inl.

    {
      return this->operation_;
    }

void TAO::Portable_Server::Servant_Upcall::operator= ( const Servant_Upcall  )  [private]
TAO_Root_POA & TAO::Portable_Server::Servant_Upcall::poa ( void   )  const

POA accessor.

Definition at line 12 of file Servant_Upcall.inl.

    {
      return *this->poa_;
    }

void TAO::Portable_Server::Servant_Upcall::poa_cleanup ( void   )  [protected]

Definition at line 379 of file Servant_Upcall.cpp.

    {
      // Decrease <poa->outstanding_requests_> now that the upcall
      // is complete.
      //
      // Note that the object adapter lock is acquired before
      // <POA::outstanding_requests_> is decreased.
      CORBA::ULong outstanding_requests =
        this->poa_->decrement_outstanding_requests ();

      // Check if all pending requests are over.
      if (outstanding_requests == 0)
        {
          // If locking is enabled and some thread is waiting in POA::destroy.
          if (this->object_adapter_->enable_locking_ &&
              this->poa_->wait_for_completion_pending_)
            {
              // Wakeup all waiting threads.
              this->poa_->outstanding_requests_condition_.broadcast ();
            }

          // Note that there is no need to check for
          // <non_servant_upcall_in_progress> since it is not possible for
          // non-servant upcalls to be in progress at this point.
          if (this->poa_->waiting_destruction_)
            {
              try
                {
                  this->poa_->complete_destruction_i ();
                }
              catch (const ::CORBA::Exception& ex)
                {
                  // Ignore exceptions
                  ex._tao_print_exception ("TAO_POA::~complete_destruction_i");
                }

              this->poa_ = 0;
            }
        }
    }

void TAO::Portable_Server::Servant_Upcall::post_invoke ( void   ) 

Run post_invoke for a request.

Definition at line 197 of file Servant_Upcall.cpp.

    {
      this->object_adapter_->servant_dispatcher_->post_invoke (
        this->poa (),
        this->pre_invoke_state_);
    }

void TAO::Portable_Server::Servant_Upcall::post_invoke_servant_cleanup ( void   )  [protected]

Definition at line 301 of file Servant_Upcall.cpp.

    {
      this->poa_->post_invoke_servant_cleanup (this->current_context_.object_id (),
                                               *this);
    }

void TAO::Portable_Server::Servant_Upcall::pre_invoke_collocated_request ( void   ) 

Run pre_invoke for a collocated request.

Definition at line 188 of file Servant_Upcall.cpp.

    {
      this->object_adapter_->servant_dispatcher_->pre_invoke_collocated_request (
        this->poa (),
        this->priority (),
        this->pre_invoke_state_);
    }

void TAO::Portable_Server::Servant_Upcall::pre_invoke_remote_request ( TAO_ServerRequest req  ) 

Run pre_invoke for a remote request.

Definition at line 178 of file Servant_Upcall.cpp.

    {
      this->object_adapter_->servant_dispatcher_->pre_invoke_remote_request (
        this->poa (),
        this->priority (),
        req,
        this->pre_invoke_state_);
    }

int TAO::Portable_Server::Servant_Upcall::prepare_for_upcall ( const TAO::ObjectKey &  key,
const char *  operation,
CORBA::Object_out  forward_to 
)

Locate POA and servant.

Definition at line 52 of file Servant_Upcall.cpp.

    {
      while (1)
        {
          bool wait_occurred_restart_call = false;

          int result =
            this->prepare_for_upcall_i (key,
                                        operation,
                                        forward_to,
                                        wait_occurred_restart_call);

          if (result == TAO_Adapter::DS_FAILED &&
              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 call prepare_for_upcall_i() again.  We also
              // need to cleanup the state of the upcall object before
              // continuing.
              this->upcall_cleanup ();
              continue;
            }
          else
            {
              return result;
            }
        }
    }

int TAO::Portable_Server::Servant_Upcall::prepare_for_upcall_i ( const TAO::ObjectKey &  key,
const char *  operation,
CORBA::Object_out  forward_to,
bool &  wait_occurred_restart_call 
)

Helper.

Definition at line 86 of file Servant_Upcall.cpp.

    {
      // Acquire the object adapter lock first.
      int result = this->object_adapter_->lock ().acquire ();
      if (result == -1)
        // Locking error.
        throw ::CORBA::OBJ_ADAPTER ();

      // We have acquired the object adapter lock.  Record this for later
      // use.
      this->state_ = OBJECT_ADAPTER_LOCK_ACQUIRED;

      // Check if a non-servant upcall is in progress.  If a non-servant
      // upcall is in progress, wait for it to complete.  Unless of
      // course, the thread making the non-servant upcall is this thread.
      this->object_adapter_->wait_for_non_servant_upcalls_to_complete ();

      // Locate the POA.
      this->object_adapter_->locate_poa (key, this->system_id_, this->poa_);

      // Check the state of the POA.
      this->poa_->check_state ();

      // Setup current for this request.
      this->current_context_.setup (this->poa_, key);

      // Increase <poa->outstanding_requests_> for the duration of finding
      // the POA, finding the servant, and making the upcall.
      this->poa_->increment_outstanding_requests ();

      // We have setup the POA Current.  Record this for later use.
      this->state_ = POA_CURRENT_SETUP;

#if (TAO_HAS_MINIMUM_CORBA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
      try
        {
#endif /* TAO_HAS_MINIMUM_CORBA */
          // Lookup the servant.
          this->servant_ =
            this->poa_->locate_servant_i (operation,
                                          this->system_id_,
                                          *this,
                                          this->current_context_,
                                          wait_occurred_restart_call);

          if (wait_occurred_restart_call)
            return TAO_Adapter::DS_FAILED;
#if (TAO_HAS_MINIMUM_CORBA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
        }
      catch (const ::PortableServer::ForwardRequest& forward_request)
        {
          forward_to =
            CORBA::Object::_duplicate (forward_request.forward_reference.in ());
          return TAO_Adapter::DS_FORWARD;
        }
#else
      ACE_UNUSED_ARG (forward_to);
#endif /* TAO_HAS_MINIMUM_CORBA */

      // Now that we know the servant.
      this->current_context_.servant (this->servant_);

      // For servants from Servant Locators, there is no active object map
      // entry.
      if (this->active_object_map_entry ())
        this->current_context_.priority (this->active_object_map_entry ()->priority_);

      if (this->state_ != OBJECT_ADAPTER_LOCK_RELEASED)
        {
          // Release the object adapter lock.
          this->object_adapter_->lock ().release ();

          // We have release the object adapter lock.  Record this for
          // later use.
          this->state_ = OBJECT_ADAPTER_LOCK_RELEASED;
        }

      // Serialize servants (if appropriate).
      this->single_threaded_poa_setup ();

      // We have acquired the servant lock.  Record this for later use.
      this->state_ = SERVANT_LOCK_ACQUIRED;

      // After this point, <this->servant_> is ready for dispatching.
      return TAO_Adapter::DS_OK;
    }

CORBA::Short TAO::Portable_Server::Servant_Upcall::priority ( void   )  const

Get the priority for the current upcall.

Definition at line 89 of file Servant_Upcall.inl.

    {
      return this->current_context_.priority ();
    }

PortableServer::Servant TAO::Portable_Server::Servant_Upcall::servant ( void   )  const

Servant accessor.

Definition at line 18 of file Servant_Upcall.inl.

    {
      return this->servant_;
    }

void TAO::Portable_Server::Servant_Upcall::servant_cleanup ( void   )  [protected]

Definition at line 345 of file Servant_Upcall.cpp.

    {
      // Cleanup servant related stuff.
      if (this->active_object_map_entry_ != 0)
        {
          // Decrement the reference count.
          CORBA::UShort const new_count =
            --this->active_object_map_entry_->reference_count_;

          if (new_count == 0)
            {
              try
                {
                  this->poa_->cleanup_servant (
                    this->active_object_map_entry_->servant_,
                    this->active_object_map_entry_->user_id_);

                }
              catch (...)
                {
                  // Ignore errors from servant cleanup ....
                }

              if (this->poa_->waiting_servant_deactivation() > 0 &&
                  this->object_adapter_->enable_locking_)
                {
                  // Wakeup all waiting threads.
                  this->poa_->servant_deactivation_condition_.broadcast ();
                }
            }
        }
    }

void TAO::Portable_Server::Servant_Upcall::single_threaded_poa_cleanup ( void   )  [protected]

Definition at line 326 of file Servant_Upcall.cpp.

    {
#if (TAO_HAS_MINIMUM_POA == 0)
      // Since the servant lock was acquired, we must release it.
      int const result = this->poa_->exit ();

      ACE_UNUSED_ARG (result);
#endif /* TAO_HAS_MINIMUM_POA == 0 */
    }

void TAO::Portable_Server::Servant_Upcall::single_threaded_poa_setup ( void   )  [protected]

Definition at line 308 of file Servant_Upcall.cpp.

    {
#if (TAO_HAS_MINIMUM_POA == 0)
      // Serialize servants (if necessary).
      //
      // Note that this lock must be acquired *after* the object adapter
      // lock has been released.  This is necessary since we cannot block
      // waiting for the servant lock while holding the object adapter
      // lock.  Otherwise, the thread that wants to release this lock will
      // not be able to do so since it can't acquire the object adapterx
      // lock.
      if (this->poa_->enter() == -1)
        // Locking error.
        throw ::CORBA::OBJ_ADAPTER ();
#endif /* !TAO_HAS_MINIMUM_POA == 0 */
    }

void TAO::Portable_Server::Servant_Upcall::state ( Servant_Upcall::State  state  ) 

Set the state.

Definition at line 101 of file Servant_Upcall.inl.

    {
      this->state_ = state;
    }

Servant_Upcall::State TAO::Portable_Server::Servant_Upcall::state ( void   )  const

Get the state.

Definition at line 95 of file Servant_Upcall.inl.

    {
      return this->state_;
    }

void TAO::Portable_Server::Servant_Upcall::upcall_cleanup ( void   )  [protected]

Clean-up / reset state of this Servant_Upcall object.

Definition at line 240 of file Servant_Upcall.cpp.

    {
      this->post_invoke ();

      switch (this->state_)
        {
        case SERVANT_LOCK_ACQUIRED:
          // Unlock servant (if appropriate).
          this->single_threaded_poa_cleanup ();

          /* FALLTHRU */

        case OBJECT_ADAPTER_LOCK_RELEASED:
          // Cleanup servant locator related state.  Note that because
          // this operation does not change any Object Adapter related
          // state, it is ok to call it outside the lock.
          this->post_invoke_servant_cleanup ();

          // Since the object adapter lock was released, we must acquire
          // it.
          //
          // Note that errors are ignored here since we cannot do much
          // with it.
          this->object_adapter_->lock ().acquire ();

          // Check if a non-servant upcall is in progress.  If a
          // non-servant upcall is in progress, wait for it to complete.
          // Unless of course, the thread making the non-servant upcall is
          // this thread.
          this->object_adapter_->wait_for_non_servant_upcalls_to_complete_no_throw ();

          // Cleanup servant related state.
          this->servant_cleanup ();

          /* FALLTHRU */

        case POA_CURRENT_SETUP:
          // Cleanup POA related state.
          this->poa_cleanup ();

          // Teardown current for this request.
          this->current_context_.teardown ();

          /* FALLTHRU */

        case OBJECT_ADAPTER_LOCK_ACQUIRED:
          // Finally, since the object adapter lock was acquired, we must
          // release it.
          this->object_adapter_->lock ().release ();

          /* FALLTHRU */

        case INITIAL_STAGE:
        default:
          // @@ Keep compiler happy, the states above are the only
          //    possible ones.
          break;
        }
    }

const PortableServer::ObjectId & TAO::Portable_Server::Servant_Upcall::user_id ( void   )  const

Definition at line 43 of file Servant_Upcall.inl.

    {
      return *(this->user_id_);
    }

void TAO::Portable_Server::Servant_Upcall::user_id ( const PortableServer::ObjectId id  ) 

User ID accessors. This is the same value returned by PortableServer::Current::get_object_id().

Definition at line 36 of file Servant_Upcall.inl.

    {
      this->user_id_ = id;
    }


Friends And Related Function Documentation

friend class ::TAO_RT_Collocation_Resolver [friend]

Definition at line 63 of file Servant_Upcall.h.


Member Data Documentation

TAO_Active_Object_Map_Entry* TAO::Portable_Server::Servant_Upcall::active_object_map_entry_ [protected]

Pointer to the entry in the TAO_Active_Object_Map corresponding to the servant for this request.

Definition at line 223 of file Servant_Upcall.h.

void* TAO::Portable_Server::Servant_Upcall::cookie_ [protected]

Servant Locator's cookie.

Definition at line 214 of file Servant_Upcall.h.

POA_Current_Impl TAO::Portable_Server::Servant_Upcall::current_context_ [protected]

Definition at line 209 of file Servant_Upcall.h.

TAO_Object_Adapter* TAO::Portable_Server::Servant_Upcall::object_adapter_ [protected]

Definition at line 196 of file Servant_Upcall.h.

const char* TAO::Portable_Server::Servant_Upcall::operation_ [protected]

Operation name for this current.

Definition at line 217 of file Servant_Upcall.h.

::TAO_Root_POA* TAO::Portable_Server::Servant_Upcall::poa_ [protected]

Definition at line 198 of file Servant_Upcall.h.

Pre_Invoke_State TAO::Portable_Server::Servant_Upcall::pre_invoke_state_ [protected]

Preinvoke data for the upcall.

Definition at line 226 of file Servant_Upcall.h.

PortableServer::Servant TAO::Portable_Server::Servant_Upcall::servant_ [protected]

Definition at line 200 of file Servant_Upcall.h.

State TAO::Portable_Server::Servant_Upcall::state_ [protected]

Definition at line 202 of file Servant_Upcall.h.

PortableServer::ObjectId TAO::Portable_Server::Servant_Upcall::system_id_ [protected]

Definition at line 205 of file Servant_Upcall.h.

CORBA::Octet TAO::Portable_Server::Servant_Upcall::system_id_buf_[TAO_POA_OBJECT_ID_BUF_SIZE] [protected]

Definition at line 204 of file Servant_Upcall.h.

const PortableServer::ObjectId* TAO::Portable_Server::Servant_Upcall::user_id_ [protected]

Definition at line 207 of file Servant_Upcall.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines