Public Member Functions | Protected Attributes

TAO::Asynch_Remote_Invocation Class Reference

#include <Asynch_Invocation.h>

Inheritance diagram for TAO::Asynch_Remote_Invocation:
Inheritance graph
[legend]
Collaboration diagram for TAO::Asynch_Remote_Invocation:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 Asynch_Remote_Invocation (CORBA::Object_ptr otarget, Profile_Transport_Resolver &resolver, TAO_Operation_Details &detail, TAO_Asynch_Reply_Dispatcher_Base *rd, bool response_expected=true)
Invocation_Status remote_invocation (ACE_Time_Value *value)

Protected Attributes

ACE_Utils::Auto_Functor
< TAO_Asynch_Reply_Dispatcher_Base,
ARDB_Refcount_Functor
safe_rd_

Detailed Description

Definition at line 43 of file Asynch_Invocation.h.


Constructor & Destructor Documentation

TAO::Asynch_Remote_Invocation::Asynch_Remote_Invocation ( CORBA::Object_ptr  otarget,
Profile_Transport_Resolver resolver,
TAO_Operation_Details detail,
TAO_Asynch_Reply_Dispatcher_Base rd,
bool  response_expected = true 
)

Definition at line 6 of file Asynch_Invocation.cpp.

               : Asynch_Invocation.cpp 84457 2009-02-13 14:52:13Z msmit $")


Member Function Documentation

Invocation_Status TAO::Asynch_Remote_Invocation::remote_invocation ( ACE_Time_Value value  ) 

Reimplemented in TAO::DII_Deferred_Invocation.

Definition at line 21 of file Asynch_Invocation.cpp.

               : Asynch_Invocation.cpp 84457 2009-02-13 14:52:13Z msmit $")

TAO_BEGIN_VERSIONED_NAMESPACE_DECL

namespace TAO
{
  Asynch_Remote_Invocation::Asynch_Remote_Invocation (
    CORBA::Object_ptr otarget,
    Profile_Transport_Resolver &resolver,
    TAO_Operation_Details &detail,
    TAO_Asynch_Reply_Dispatcher_Base *rd,
    bool response_expected)
    : Synch_Twoway_Invocation (otarget,
                               resolver,
                               detail,
                               response_expected)
    , safe_rd_ (rd)
  {
  }

  Invocation_Status
  Asynch_Remote_Invocation::remote_invocation (ACE_Time_Value *max_wait_time)
  {
    Invocation_Status s = TAO_INVOKE_FAILURE;

#if TAO_HAS_INTERCEPTORS == 1
    s = this->send_request_interception ();

    if (s != TAO_INVOKE_SUCCESS)
      return s;

    // We have started the interception flow. We need to call the
    // ending interception flow if things go wrong. The purpose of the
    // try block is to take care of the cases when things go wrong.
    try
      {
#endif /* TAO_HAS_INTERCEPTORS */
        TAO_Transport* const transport = this->resolver_.transport ();

        if (!transport)
          {
            // Way back, we failed to find a profile we could connect to.
            // We've come this far only so we reach the interception points
            // in case they can fix things. Time to bail....
            throw CORBA::TRANSIENT (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
          }

        ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon,
                          transport->output_cdr_lock (), TAO_INVOKE_FAILURE);

        TAO_OutputCDR & cdr =
          this->resolver_.transport ()->messaging_object ()->out_stream ();

        // Oneway semantics.  See comments for below send_message()
        // call.
        cdr.message_attributes (this->details_.request_id (),
                                this->resolver_.stub (),
                                TAO_ONEWAY_REQUEST,
                                max_wait_time);

        this->write_header (cdr);

        this->marshal_data (cdr);

        // Register a reply dispatcher for this invocation. Use the
        // preallocated reply dispatcher.
        TAO_Bind_Dispatcher_Guard dispatch_guard (
          this->details_.request_id (),
          this->safe_rd_.get (),
          transport->tms ());

        // Now that we have bound the reply dispatcher to the map, just
        // loose ownership of the reply dispatcher.
        this->safe_rd_.release ();

        if (dispatch_guard.status () != 0)
          {
            // @@ What is the right way to handle this error? Do we need
            // to call the interceptors in this case?
            throw ::CORBA::INTERNAL (TAO::VMCID, CORBA::COMPLETED_NO);
          }

        // Do not unbind during destruction. We need the entry to be
        // there in the map since the reply dispatcher depends on
        // that. This is also a trigger to loose the ownership of the
        // reply dispatcher.
        dispatch_guard.status (TAO_Bind_Dispatcher_Guard::NO_UNBIND);

        // Send it as a oneway request. It will make all the required
        // paraphernalia within the ORB to fire, like buffering if
        // send blocks etc.
        s = this->send_message (cdr,
                                TAO_ONEWAY_REQUEST,
                                max_wait_time);

        ace_mon.release();

#if TAO_HAS_INTERCEPTORS == 1
        // NOTE: We don't need to do the auto_ptr <> trick. We got here
        // in the first place since the message was sent properly,
        // which implies a reply would be available. Therefore the
        // reply dispatcher should be available for another thread to
        // collect and dispatch the reply. In MT cases, things are
        // more hairy. Just imagine what happens when another thread
        // is collecting the reply when we are happily invoking
        // interceptors?

        // Nothing great on here. If we get a restart during send or a
        // proper send, we are supposed to call receiver_other ()
        // interception point. So we do that here
        Invocation_Status const tmp = this->receive_other_interception ();

        // We got an error during the interception.
        if (s == TAO_INVOKE_SUCCESS && tmp != TAO_INVOKE_SUCCESS)
          s = tmp;
#endif /* TAO_HAS_INTERCEPTORS */

        // If an error occurred just return. At this point all the
        // endpoint interception would have been invoked. The callee
        // would take care of the rest.
        if (s != TAO_INVOKE_SUCCESS)
          return s;

        // NOTE: Not sure how things are handles with exclusive muxed
        // strategy.
        if (transport->idle_after_send ())
          (void) this->resolver_.transport_released ();

#if TAO_HAS_INTERCEPTORS == 1
      }
    catch ( ::CORBA::Exception& ex)
      {

        PortableInterceptor::ReplyStatus const status =
          this->handle_any_exception (&ex);

        if (status == PortableInterceptor::LOCATION_FORWARD ||
            status == PortableInterceptor::TRANSPORT_RETRY)
          s = TAO_INVOKE_RESTART;
        else if (status == PortableInterceptor::SYSTEM_EXCEPTION


Member Data Documentation

ACE_Utils::Auto_Functor<TAO_Asynch_Reply_Dispatcher_Base, ARDB_Refcount_Functor> TAO::Asynch_Remote_Invocation::safe_rd_ [protected]

Definition at line 59 of file Asynch_Invocation.h.


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