LocateRequest_Invocation.cpp

Go to the documentation of this file.
00001 #include "tao/LocateRequest_Invocation.h"
00002 #include "tao/Profile_Transport_Resolver.h"
00003 #include "tao/operation_details.h"
00004 #include "tao/Stub.h"
00005 #include "tao/Bind_Dispatcher_Guard.h"
00006 #include "tao/Transport.h"
00007 #include "tao/Synch_Reply_Dispatcher.h"
00008 #include "tao/GIOP_Utils.h"
00009 #include "tao/Profile.h"
00010 #include "tao/ORB_Constants.h"
00011 
00012 #include "ace/Countdown_Time.h"
00013 
00014 ACE_RCSID (tao,
00015            LocateRequest_Invocation,
00016            "LocateRequest_Invocation.cpp,v 1.11 2006/04/19 09:01:40 jwillemsen Exp")
00017 
00018 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 namespace TAO
00021 {
00022   LocateRequest_Invocation::LocateRequest_Invocation (
00023       CORBA::Object_ptr otarget,
00024       Profile_Transport_Resolver &resolver,
00025       TAO_Operation_Details &detail
00026     )
00027     : Synch_Twoway_Invocation (otarget,
00028                                resolver,
00029                                detail)
00030   {
00031   }
00032 
00033   Invocation_Status
00034   LocateRequest_Invocation::invoke (ACE_Time_Value *max_wait_time
00035                                     ACE_ENV_ARG_DECL)
00036     ACE_THROW_SPEC ((CORBA::Exception))
00037   {
00038     ACE_Countdown_Time countdown (max_wait_time);
00039 
00040     TAO_Synch_Reply_Dispatcher rd (this->resolver_.stub ()->orb_core (),
00041                                    this->details_.reply_service_info ());
00042 
00043     // Register a reply dispatcher for this invocation. Use the
00044     // preallocated reply dispatcher.
00045     TAO_Bind_Dispatcher_Guard dispatch_guard (this->details_.request_id (),
00046                                               &rd,
00047                                               this->resolver_.transport ()->tms ());
00048 
00049     if (dispatch_guard.status () != 0)
00050       {
00051         // @@ What is the right way to handle this error? Do we need
00052         // to call the interceptors in this case?
00053         this->resolver_.transport ()->close_connection ();
00054 
00055         ACE_THROW_RETURN (CORBA::INTERNAL (TAO::VMCID,
00056                                            CORBA::COMPLETED_NO),
00057                           TAO_INVOKE_FAILURE);
00058       }
00059 
00060     TAO_Target_Specification tspec;
00061     this->init_target_spec (tspec ACE_ENV_ARG_PARAMETER);
00062     ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
00063 
00064     TAO_Transport *transport =
00065       this->resolver_.transport ();
00066 
00067     TAO_OutputCDR &cdr = transport->out_stream ();
00068 
00069     int const retval =
00070       transport->generate_locate_request (tspec,
00071                                           this->details_,
00072                                           cdr);
00073     ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
00074 
00075     if (retval == -1)
00076       return TAO_INVOKE_FAILURE;
00077 
00078     countdown.update ();
00079 
00080     Invocation_Status s =
00081       this->send_message (cdr,
00082                           TAO_Transport::TAO_TWOWAY_REQUEST,
00083                           max_wait_time
00084                           ACE_ENV_ARG_PARAMETER);
00085     ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
00086 
00087     if (s != TAO_INVOKE_SUCCESS)
00088       return s;
00089 
00090     countdown.update ();
00091 
00092     // For some strategies one may want to release the transport
00093     // back to  cache. If the idling is successfull let the
00094     // resolver about that.
00095     if (this->resolver_.transport ()->idle_after_send ())
00096       this->resolver_.transport_released ();
00097 
00098     s =
00099       this->wait_for_reply (max_wait_time,
00100                             rd,
00101                             dispatch_guard
00102                             ACE_ENV_ARG_PARAMETER);
00103     ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
00104 
00105     s = this->check_reply (rd
00106                            ACE_ENV_ARG_PARAMETER);
00107     ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
00108 
00109     // For some strategies one may want to release the transport
00110     // back to  cache after receiving the reply. If the idling is
00111     // successfull let the resolver about that.
00112     if (this->resolver_.transport ()->idle_after_reply ())
00113       this->resolver_.transport_released ();
00114 
00115     return s;
00116   }
00117 
00118   Invocation_Status
00119   LocateRequest_Invocation::check_reply (TAO_Synch_Reply_Dispatcher &rd
00120                                          ACE_ENV_ARG_DECL)
00121   {
00122     TAO_InputCDR &cdr =
00123       rd.reply_cdr ();
00124 
00125     // Set the translators
00126     this->resolver_.transport ()->assign_translators (&cdr, 0);
00127 
00128     switch (rd.reply_status ())
00129       {
00130       case TAO_GIOP_OBJECT_HERE:
00131         break;
00132       case TAO_GIOP_UNKNOWN_OBJECT:
00133         ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (TAO::VMCID,
00134                                                    CORBA::COMPLETED_YES),
00135                           TAO_INVOKE_FAILURE);
00136       case TAO_GIOP_OBJECT_FORWARD:
00137       case TAO_GIOP_OBJECT_FORWARD_PERM:
00138         return this->location_forward (cdr
00139                                        ACE_ENV_ARG_PARAMETER);
00140 
00141       case TAO_GIOP_LOC_SYSTEM_EXCEPTION:
00142         {
00143           // Pull the exception from the stream.
00144           CORBA::String_var buf;
00145 
00146           if ((cdr >> buf.inout ()) == 0)
00147             {
00148               // Could not demarshal the exception id, raise a local
00149               // CORBA::MARSHAL exception.
00150               ACE_THROW_RETURN (CORBA::MARSHAL (TAO::VMCID,
00151                                                 CORBA::COMPLETED_MAYBE),
00152                                 TAO_INVOKE_SYSTEM_EXCEPTION);
00153             }
00154 
00155           // This kind of exception shouldn't happen with locate requests,
00156           // but if it does, we turn it into a CORBA::UNKNOWN exception.
00157           ACE_THROW_RETURN (CORBA::UNKNOWN (TAO::VMCID,
00158                                             CORBA::COMPLETED_YES),
00159                             TAO_INVOKE_SYSTEM_EXCEPTION);
00160         }
00161       case TAO_GIOP_LOC_NEEDS_ADDRESSING_MODE:
00162         {
00163           // We have received an exception with a request to change the
00164           // addressing mode. First let us read the mode that the
00165           // server/agent asks for.
00166           CORBA::Short addr_mode = 0;
00167 
00168           if (cdr.read_short (addr_mode) == 0)
00169             {
00170               // Could not demarshal the addressing disposition, raise a local
00171               // CORBA::MARSHAL exception.
00172               ACE_THROW_RETURN (CORBA::MARSHAL (TAO::VMCID,
00173                                                 CORBA::COMPLETED_MAYBE),
00174                                 TAO_INVOKE_SUCCESS);
00175             }
00176 
00177           // Now set this addressing mode in the profile, so that
00178           // the next invocation need not go through this.
00179           this->resolver_.profile ()->addressing_mode (addr_mode
00180                                                        ACE_ENV_ARG_PARAMETER);
00181           ACE_CHECK_RETURN (TAO_INVOKE_SUCCESS);
00182 
00183           // Restart the invocation.
00184           return TAO_INVOKE_RESTART;
00185         }
00186       }
00187 
00188     return TAO_INVOKE_SUCCESS;
00189   }
00190 }
00191 
00192 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 11:54:15 2006 for TAO by doxygen 1.3.6