Remote_Invocation.cpp

Go to the documentation of this file.
00001 //$Id: Remote_Invocation.cpp 80292 2007-12-17 20:38:32Z johnnyw $
00002 
00003 #include "tao/Remote_Invocation.h"
00004 #include "tao/Profile.h"
00005 #include "tao/Profile_Transport_Resolver.h"
00006 #include "tao/Stub.h"
00007 #include "tao/Connection_Handler.h"
00008 #include "tao/operation_details.h"
00009 #include "tao/ORB_Core.h"
00010 #include "tao/Protocols_Hooks.h"
00011 #include "tao/Network_Priority_Protocols_Hooks.h"
00012 #include "tao/debug.h"
00013 #include "tao/SystemException.h"
00014 
00015 ACE_RCSID (tao,
00016            Remote_Invocation,
00017            "$Id: Remote_Invocation.cpp 80292 2007-12-17 20:38:32Z johnnyw $")
00018 
00019 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00020 
00021 namespace TAO
00022 {
00023   Remote_Invocation::Remote_Invocation (
00024     CORBA::Object_ptr otarget,
00025     Profile_Transport_Resolver &resolver,
00026     TAO_Operation_Details &detail,
00027     bool response_expected)
00028     : Invocation_Base (otarget,
00029                        resolver.object (),
00030                        resolver.stub (),
00031                        detail,
00032                        response_expected,
00033                        true /* request_is_remote */ )
00034     , resolver_ (resolver)
00035   {
00036   }
00037 
00038   void
00039   Remote_Invocation::init_target_spec (TAO_Target_Specification &target_spec)
00040   {
00041     /**
00042      * Mega hack for RTCORBA start. I don't think that
00043      * PortableInterceptor  would work here esp. for RTCORBA. PI needs
00044      * to be improved to  help our cause.
00045      */
00046     this->resolver_.stub ()->orb_core ()->service_context_list (
00047       this->resolver_.stub (),
00048       this->details_.request_service_context (),
00049       0);
00050     /**
00051      * Mega hack for RTCORBA END
00052      */
00053 
00054     TAO_Profile *pfile = this->resolver_.profile ();
00055 
00056     // Set the target specification mode
00057     switch (pfile->addressing_mode ())
00058       {
00059       case TAO_Target_Specification::Key_Addr:
00060         target_spec.target_specifier (pfile->object_key ());
00061         break;
00062       case TAO_Target_Specification::Profile_Addr:
00063         {
00064           IOP::TaggedProfile *tp =
00065             pfile->create_tagged_profile ();
00066 
00067           if (tp)
00068             {
00069               target_spec.target_specifier (*tp);
00070             }
00071         }
00072         break;
00073 
00074     case TAO_Target_Specification::Reference_Addr:
00075       // We need to call the method seperately. If there is no
00076       // IOP::IOR info, the call would create the info and return the
00077       // index that we need.
00078       CORBA::ULong index = 0;
00079       IOP::IOR *ior_info = 0;
00080 
00081       if (this->resolver_.stub ()->create_ior_info (ior_info, index) == -1)
00082         {
00083           if (TAO_debug_level > 0)
00084             {
00085               ACE_ERROR ((LM_ERROR,
00086                           ACE_TEXT ("TAO (%P|%t) - ")
00087                           ACE_TEXT ("Remote_Invocation::init_target_spec, ")
00088                           ACE_TEXT ("Error in finding index for ")
00089                           ACE_TEXT ("IOP::IOR \n")));
00090             }
00091 
00092           return;
00093         }
00094 
00095       target_spec.target_specifier (*ior_info, index);
00096       break;
00097     }
00098   }
00099 
00100   void
00101   Remote_Invocation::write_header (TAO_OutputCDR &out_stream)
00102   {
00103     TAO_Target_Specification spec;
00104     this->init_target_spec (spec);
00105 
00106     this->resolver_.transport ()->clear_translators (0, &out_stream);
00107 
00108     // Send the request for the header
00109     if (this->resolver_.transport ()->generate_request_header (this->details_,
00110                                                                spec,
00111                                                                out_stream) == -1)
00112       {
00113         throw ::CORBA::MARSHAL ();
00114       }
00115 
00116     this->resolver_.transport ()->assign_translators (0, &out_stream);
00117   }
00118 
00119   void
00120   Remote_Invocation::marshal_data (TAO_OutputCDR &out_stream)
00121   {
00122     if (this->details_.marshal_args (out_stream) == false)
00123       {
00124         throw ::CORBA::MARSHAL ();
00125       }
00126   }
00127 
00128   Invocation_Status
00129   Remote_Invocation::send_message (TAO_OutputCDR &cdr,
00130                                    TAO_Transport::TAO_Message_Semantics message_semantics,
00131                                    ACE_Time_Value *max_wait_time)
00132   {
00133     TAO_Protocols_Hooks *tph =
00134       this->resolver_.stub ()->orb_core ()->get_protocols_hooks ();
00135 
00136     TAO_Network_Priority_Protocols_Hooks *nph =
00137       this->resolver_.stub ()->orb_core ()->
00138         get_network_priority_protocols_hooks ();
00139 
00140     TAO_Connection_Handler *connection_handler =
00141       this->resolver_.transport ()->connection_handler ();
00142 
00143     if (nph != 0)
00144       {
00145         // nph = 0, means DiffServ library is not used
00146         // nph = 0, means DiffServ library is used, and
00147         // request DSCP and reply DSCP are set.
00148         // Note that the application could still be using
00149         // RTCORBA, but still setting DIffServ codepoints
00150         // using the DiffServ library takes precedence.
00151         //
00152         CORBA::Long const dscp = nph->get_dscp_codepoint (this->resolver_.stub (),
00153           this->resolver_.object ());
00154         connection_handler->set_dscp_codepoint (dscp);
00155       }
00156     else if (tph != 0)
00157       {
00158         // If we execute this code, DiffServ library is not used,
00159         // but RTCORBA could be used.
00160         // Which means that using the enable_network_priority flag,
00161         // the application might want to set DiffServ codepoints.
00162         // Check if that is the case.
00163         //
00164         CORBA::Boolean const set_client_network_priority =
00165           tph->set_client_network_priority (
00166             this->resolver_.transport ()->tag (),
00167             this->resolver_.stub ());
00168         connection_handler->set_dscp_codepoint (set_client_network_priority);
00169       }
00170 
00171     // Note that if noth nph and tph are 0, then we do not make any
00172     // virtual calls any more, because we have removed the default
00173     // implementations.
00174 
00175     int const retval =
00176       this->resolver_.transport ()->send_request (
00177         this->resolver_.stub (),
00178         this->resolver_.stub ()->orb_core (),
00179         cdr,
00180         message_semantics,
00181         max_wait_time);
00182 
00183     if (retval == -1)
00184       {
00185         if (errno == ETIME)
00186           {
00187             // We sent a message already and we haven't gotten a
00188             // reply.  Just throw TIMEOUT with *COMPLETED_MAYBE*.
00189             throw ::CORBA::TIMEOUT (
00190               CORBA::SystemException::_tao_minor_code (
00191                 TAO_TIMEOUT_SEND_MINOR_CODE,
00192                 errno),
00193               CORBA::COMPLETED_MAYBE);
00194           }
00195 
00196         if (TAO_debug_level > 2)
00197           {
00198             ACE_DEBUG ((LM_DEBUG,
00199                         ACE_TEXT ("TAO (%P|%t) - ")
00200                         ACE_TEXT ("Remote_Invocation::send_message, ")
00201                         ACE_TEXT ("failure while sending message \n")));
00202           }
00203 
00204         // Close the transport and all the associated stuff along with
00205         // it.
00206         this->resolver_.transport ()->close_connection ();
00207         this->resolver_.stub ()->reset_profiles ();
00208         return TAO_INVOKE_RESTART;
00209       }
00210 
00211     this->resolver_.stub ()->set_valid_profile ();
00212     return TAO_INVOKE_SUCCESS;
00213   }
00214 }
00215 
00216 TAO_END_VERSIONED_NAMESPACE_DECL

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