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 #include "tao/SystemException.h"
00012 
00013 #include "ace/Countdown_Time.h"
00014 
00015 ACE_RCSID (tao,
00016            LocateRequest_Invocation,
00017            "$Id: LocateRequest_Invocation.cpp 79705 2007-09-24 07:45:37Z johnnyw $")
00018 
00019 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00020 
00021 namespace TAO
00022 {
00023   LocateRequest_Invocation::LocateRequest_Invocation (
00024       CORBA::Object_ptr otarget,
00025       Profile_Transport_Resolver &resolver,
00026       TAO_Operation_Details &detail
00027     )
00028     : Synch_Twoway_Invocation (otarget,
00029                                resolver,
00030                                detail)
00031   {
00032   }
00033 
00034   Invocation_Status
00035   LocateRequest_Invocation::invoke (ACE_Time_Value *max_wait_time)
00036   {
00037     ACE_Countdown_Time countdown (max_wait_time);
00038 
00039     TAO_Synch_Reply_Dispatcher rd (this->resolver_.stub ()->orb_core (),
00040                                    this->details_.reply_service_info ());
00041 
00042     // Register a reply dispatcher for this invocation. Use the
00043     // preallocated reply dispatcher.
00044     TAO_Bind_Dispatcher_Guard dispatch_guard (this->details_.request_id (),
00045                                               &rd,
00046                                               this->resolver_.transport ()->tms ());
00047 
00048     if (dispatch_guard.status () != 0)
00049       {
00050         // @@ What is the right way to handle this error? Do we need
00051         // to call the interceptors in this case?
00052         this->resolver_.transport ()->close_connection ();
00053 
00054         throw ::CORBA::INTERNAL (TAO::VMCID, CORBA::COMPLETED_NO);
00055       }
00056 
00057     TAO_Target_Specification tspec;
00058     this->init_target_spec (tspec);
00059 
00060     TAO_Transport *transport = this->resolver_.transport ();
00061 
00062     TAO_OutputCDR &cdr = transport->out_stream ();
00063 
00064     if (transport->generate_locate_request (tspec, this->details_, cdr) == -1)
00065       return TAO_INVOKE_FAILURE;
00066 
00067     countdown.update ();
00068 
00069     Invocation_Status s =
00070       this->send_message (cdr, TAO_Transport::TAO_TWOWAY_REQUEST, max_wait_time);
00071 
00072     if (s != TAO_INVOKE_SUCCESS)
00073       return s;
00074 
00075     countdown.update ();
00076 
00077     // For some strategies one may want to release the transport
00078     // back to  cache. If the idling is successfull let the
00079     // resolver about that.
00080     if (this->resolver_.transport ()->idle_after_send ())
00081       this->resolver_.transport_released ();
00082 
00083     s = this->wait_for_reply (max_wait_time, rd, dispatch_guard);
00084 
00085     s = this->check_reply (rd);
00086 
00087     // For some strategies one may want to release the transport
00088     // back to  cache after receiving the reply. If the idling is
00089     // successfull let the resolver about that.
00090     if (this->resolver_.transport ()->idle_after_reply ())
00091       this->resolver_.transport_released ();
00092 
00093     return s;
00094   }
00095 
00096   Invocation_Status
00097   LocateRequest_Invocation::check_reply (TAO_Synch_Reply_Dispatcher &rd)
00098   {
00099     TAO_InputCDR &cdr = rd.reply_cdr ();
00100 
00101     // Set the translators
00102     this->resolver_.transport ()->assign_translators (&cdr, 0);
00103 
00104     switch (rd.locate_reply_status ())
00105       {
00106       case GIOP::OBJECT_HERE:
00107         break;
00108       case GIOP::UNKNOWN_OBJECT:
00109         throw ::CORBA::OBJECT_NOT_EXIST (TAO::VMCID, CORBA::COMPLETED_YES);
00110       case GIOP::OBJECT_FORWARD:
00111       case GIOP::OBJECT_FORWARD_PERM:
00112         return this->location_forward (cdr);
00113       case GIOP::LOC_SYSTEM_EXCEPTION:
00114         {
00115           // Pull the exception from the stream.
00116           CORBA::String_var buf;
00117 
00118           if ((cdr >> buf.inout ()) == 0)
00119             {
00120               // Could not demarshal the exception id, raise a local
00121               // CORBA::MARSHAL exception.
00122               throw ::CORBA::MARSHAL (TAO::VMCID, CORBA::COMPLETED_MAYBE);
00123             }
00124 
00125           // This kind of exception shouldn't happen with locate requests,
00126           // but if it does, we turn it into a CORBA::UNKNOWN exception.
00127           throw ::CORBA::UNKNOWN (TAO::VMCID, CORBA::COMPLETED_YES);
00128         }
00129       case GIOP::LOC_NEEDS_ADDRESSING_MODE:
00130         {
00131           // We have received an exception with a request to change the
00132           // addressing mode. First let us read the mode that the
00133           // server/agent asks for.
00134           CORBA::Short addr_mode = 0;
00135 
00136           if (cdr.read_short (addr_mode) == 0)
00137             {
00138               // Could not demarshal the addressing disposition, raise a local
00139               // CORBA::MARSHAL exception.
00140               throw ::CORBA::MARSHAL (TAO::VMCID, CORBA::COMPLETED_MAYBE);
00141             }
00142 
00143           // Now set this addressing mode in the profile, so that
00144           // the next invocation need not go through this.
00145           this->resolver_.profile ()->addressing_mode (addr_mode);
00146 
00147           // Restart the invocation.
00148           return TAO_INVOKE_RESTART;
00149         }
00150       }
00151 
00152     return TAO_INVOKE_SUCCESS;
00153   }
00154 }
00155 
00156 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:37:52 2010 for TAO by  doxygen 1.4.7