1 #include "tao/Remote_Invocation.h"
2 #include "tao/Profile.h"
3 #include "tao/Profile_Transport_Resolver.h"
5 #include "tao/Connection_Handler.h"
6 #include "tao/ORB_Core.h"
7 #include "tao/Protocols_Hooks.h"
8 #include "tao/Network_Priority_Protocols_Hooks.h"
10 #include "tao/SystemException.h"
12 #if !defined (__ACE_INLINE__)
13 # include "tao/Remote_Invocation.inl"
14 #endif /* __ACE_INLINE__ */
16 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
20 Remote_Invocation::Remote_Invocation (
21 CORBA::Object_ptr otarget
,
22 Profile_Transport_Resolver
&resolver
,
23 TAO_Operation_Details
&detail
,
24 bool response_expected
)
25 : Invocation_Base (otarget
,
30 true /* request_is_remote */ )
31 , resolver_ (resolver
)
32 , byte_order_(TAO_ENCAP_BYTE_ORDER
)
37 Remote_Invocation::init_target_spec (TAO_Target_Specification
&target_spec
,
38 TAO_OutputCDR
&output
)
40 // Generate all service contexts
41 this->resolver_
.stub ()->orb_core ()->service_context_registry ().
42 generate_service_context (
43 this->resolver_
.stub (),
44 *this->resolver_
.transport (),
49 TAO_Profile
*pfile
= this->resolver_
.profile ();
51 // Set the target specification mode
52 switch (pfile
->addressing_mode ())
54 case TAO_Target_Specification::Key_Addr
:
55 target_spec
.target_specifier (pfile
->object_key ());
57 case TAO_Target_Specification::Profile_Addr
:
59 IOP::TaggedProfile
*tp
= pfile
->create_tagged_profile ();
63 target_spec
.target_specifier (*tp
);
68 case TAO_Target_Specification::Reference_Addr
:
69 // We need to call the method separately. If there is no
70 // IOP::IOR info, the call would create the info and return the
71 // index that we need.
72 CORBA::ULong index
= 0;
73 IOP::IOR
*ior_info
= nullptr;
75 if (this->resolver_
.stub ()->create_ior_info (ior_info
, index
) == -1)
77 if (TAO_debug_level
> 0)
79 TAOLIB_ERROR ((LM_ERROR
,
80 ACE_TEXT ("TAO (%P|%t) - ")
81 ACE_TEXT ("Remote_Invocation::init_target_spec, ")
82 ACE_TEXT ("Error in finding index for ")
83 ACE_TEXT ("IOP::IOR\n")));
89 target_spec
.target_specifier (*ior_info
, index
);
95 Remote_Invocation::write_header (TAO_OutputCDR
&out_stream
)
97 this->resolver_
.transport ()->clear_translators (nullptr, &out_stream
);
99 TAO_Target_Specification spec
;
100 this->init_target_spec (spec
, out_stream
);
102 // Send the request for the header
103 if (this->resolver_
.transport ()->generate_request_header (this->details_
,
107 throw ::CORBA::MARSHAL ();
110 this->resolver_
.transport ()->assign_translators (nullptr, &out_stream
);
114 Remote_Invocation::send_message (TAO_OutputCDR
&cdr
,
115 TAO_Message_Semantics message_semantics
,
116 ACE_Time_Value
*max_wait_time
)
118 TAO_Protocols_Hooks
*tph
=
119 this->resolver_
.stub ()->orb_core ()->get_protocols_hooks ();
121 TAO_Network_Priority_Protocols_Hooks
*nph
=
122 this->resolver_
.stub ()->orb_core ()->
123 get_network_priority_protocols_hooks ();
125 TAO_Connection_Handler
*connection_handler
=
126 this->resolver_
.transport ()->connection_handler ();
130 // nph = 0, means DiffServ library is not used
131 // nph = 0, means DiffServ library is used, and
132 // request DSCP and reply DSCP are set.
133 // Note that the application could still be using
134 // RTCORBA, but still setting DIffServ codepoints
135 // using the DiffServ library takes precedence.
137 CORBA::Long
const dscp
= nph
->get_dscp_codepoint (this->resolver_
.stub (),
138 this->resolver_
.object ());
139 connection_handler
->set_dscp_codepoint (dscp
);
141 else if (tph
!= nullptr)
143 // If we execute this code, DiffServ library is not used,
144 // but RTCORBA could be used.
145 // Which means that using the enable_network_priority flag,
146 // the application might want to set DiffServ codepoints.
147 // Check if that is the case.
149 CORBA::Boolean
const set_client_network_priority
=
150 tph
->set_client_network_priority (
151 this->resolver_
.transport ()->tag (),
152 this->resolver_
.stub ());
153 connection_handler
->set_dscp_codepoint (set_client_network_priority
);
156 // Note that if noth nph and tph are 0, then we do not make any
157 // virtual calls any more, because we have removed the default
160 if (! this->resolver_
.transport ()->is_connected()) {
161 throw ::CORBA::TRANSIENT (CORBA::OMGVMCID
| 2, CORBA::COMPLETED_NO
);
165 this->resolver_
.transport ()->send_request (
166 this->resolver_
.stub (),
167 this->resolver_
.stub ()->orb_core (),
176 // We sent a message already and we haven't gotten a
177 // reply. Just throw TIMEOUT with *COMPLETED_MAYBE*.
178 throw ::CORBA::TIMEOUT (
179 CORBA::SystemException::_tao_minor_code (
180 TAO_TIMEOUT_SEND_MINOR_CODE
,
182 CORBA::COMPLETED_MAYBE
);
185 if (TAO_debug_level
> 2)
187 TAOLIB_DEBUG ((LM_DEBUG
,
188 ACE_TEXT ("TAO (%P|%t) - ")
189 ACE_TEXT ("Remote_Invocation::send_message, ")
190 ACE_TEXT ("failure while sending message\n")));
193 // Close the transport and all the associated stuff along with
195 this->resolver_
.transport ()->close_connection ();
196 this->resolver_
.stub ()->reset_profiles ();
197 return TAO_INVOKE_RESTART
;
200 this->resolver_
.stub ()->set_valid_profile ();
201 return TAO_INVOKE_SUCCESS
;
205 TAO_END_VERSIONED_NAMESPACE_DECL