00001
00002
00003 #include "tao/Invocation_Adapter.h"
00004 #include "tao/Profile_Transport_Resolver.h"
00005 #include "tao/operation_details.h"
00006 #include "tao/Stub.h"
00007 #include "tao/ORB_Core.h"
00008 #include "tao/Synch_Invocation.h"
00009 #include "tao/debug.h"
00010 #include "tao/Collocated_Invocation.h"
00011 #include "tao/Transport.h"
00012 #include "tao/Transport_Mux_Strategy.h"
00013 #include "tao/Collocation_Proxy_Broker.h"
00014 #include "tao/GIOP_Utils.h"
00015 #include "tao/TAOC.h"
00016 #include "tao/SystemException.h"
00017 #include "ace/Service_Config.h"
00018
00019 #if !defined (__ACE_INLINE__)
00020 # include "tao/Invocation_Adapter.inl"
00021 #endif
00022
00023
00024 ACE_RCSID (tao,
00025 Invocation_Adapter,
00026 "$Id: Invocation_Adapter.cpp 85951 2009-07-09 13:11:43Z sma $")
00027
00028 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00029
00030 namespace TAO
00031 {
00032 Invocation_Adapter::~Invocation_Adapter (void)
00033 {
00034 }
00035
00036 void
00037 Invocation_Adapter::invoke (TAO::Exception_Data *ex_data,
00038 unsigned long ex_count)
00039 {
00040
00041 TAO_Stub *stub = this->get_stub ();
00042
00043 TAO_Operation_Details op_details (this->operation_,
00044 this->op_len_,
00045 this->args_,
00046 this->number_args_,
00047 ex_data,
00048 ex_count);
00049
00050 this->invoke_i (stub, op_details);
00051 }
00052
00053 void
00054 Invocation_Adapter::invoke_i (TAO_Stub *stub, TAO_Operation_Details &details)
00055 {
00056
00057
00058
00059
00060
00061 ACE_Service_Config_Guard scg (stub->orb_core ()->configuration ());
00062
00063
00064 CORBA::Object_var effective_target =
00065 CORBA::Object::_duplicate (this->target_);
00066
00067
00068 TAO::Invocation_Status status = TAO_INVOKE_START;
00069 ACE_Time_Value *max_wait_time = 0;
00070 ACE_Time_Value tmp_wait_time = ACE_Time_Value::zero;
00071 if (this->get_timeout (stub, tmp_wait_time))
00072 {
00073 max_wait_time= &tmp_wait_time;
00074 }
00075
00076 while (status == TAO_INVOKE_START || status == TAO_INVOKE_RESTART)
00077 {
00078
00079 Collocation_Strategy strat = TAO_CS_REMOTE_STRATEGY;
00080
00081
00082
00083
00084
00085 if (cpb_ != 0 || effective_target->_servant () != 0)
00086 {
00087 strat = TAO_ORB_Core::collocation_strategy (effective_target.in ());
00088 }
00089
00090 if (strat == TAO_CS_REMOTE_STRATEGY || strat == TAO_CS_LAST)
00091 {
00092 status =
00093 this->invoke_remote_i (stub,
00094 details,
00095 effective_target,
00096 max_wait_time);
00097 }
00098 else
00099 {
00100 if (strat == TAO_CS_THRU_POA_STRATEGY)
00101 {
00102 (void) this->set_response_flags (stub, details);
00103 }
00104
00105 status =
00106 this->invoke_collocated_i (stub,
00107 details,
00108 effective_target,
00109 strat);
00110 }
00111
00112 if (status == TAO_INVOKE_RESTART)
00113 {
00114 details.reset_request_service_info ();
00115 details.reset_reply_service_info ();
00116
00117 if (TAO_debug_level > 2)
00118 {
00119 ACE_DEBUG ((LM_DEBUG,
00120 ACE_TEXT("TAO (%P|%t) - Invocation_Adapter::invoke_i, ")
00121 ACE_TEXT("handling forwarded locations\n")));
00122 }
00123 }
00124 }
00125 }
00126
00127 bool
00128 Invocation_Adapter::get_timeout (TAO_Stub *stub, ACE_Time_Value &timeout)
00129 {
00130 bool has_timeout = false;
00131 this->target_->orb_core ()->call_timeout_hook (stub, has_timeout, timeout);
00132
00133 return has_timeout;
00134 }
00135
00136 TAO_Stub *
00137 Invocation_Adapter::get_stub (void) const
00138 {
00139 TAO_Stub * const stub = this->target_->_stubobj ();
00140
00141 if (stub == 0)
00142 throw ::CORBA::INTERNAL (
00143 CORBA::SystemException::_tao_minor_code (
00144 TAO::VMCID,
00145 EINVAL),
00146 CORBA::COMPLETED_NO);
00147
00148 return stub;
00149 }
00150
00151 Invocation_Status
00152 Invocation_Adapter::invoke_collocated_i (TAO_Stub *stub,
00153 TAO_Operation_Details &details,
00154 CORBA::Object_var &effective_target,
00155 Collocation_Strategy strat)
00156 {
00157
00158
00159 ACE_ASSERT (cpb_ != 0
00160 || (strat == TAO_CS_THRU_POA_STRATEGY
00161 && effective_target->_servant () != 0));
00162
00163
00164 TAO::Invocation_Status status = TAO_INVOKE_START;
00165
00166 Collocated_Invocation coll_inv (this->target_,
00167 effective_target.in (),
00168 stub,
00169 details,
00170 this->type_ == TAO_TWOWAY_INVOCATION);
00171
00172 status = coll_inv.invoke (this->cpb_, strat);
00173
00174 if (status == TAO_INVOKE_RESTART &&
00175 (coll_inv.reply_status () == GIOP::LOCATION_FORWARD ||
00176 coll_inv.reply_status () == GIOP::LOCATION_FORWARD_PERM))
00177 {
00178 CORBA::Boolean const is_permanent_forward =
00179 (coll_inv.reply_status () == GIOP::LOCATION_FORWARD_PERM);
00180
00181 effective_target = coll_inv.steal_forwarded_reference ();
00182
00183 this->object_forwarded (effective_target, stub, is_permanent_forward);
00184 }
00185
00186 return status;
00187 }
00188
00189 void
00190 Invocation_Adapter::set_response_flags (
00191 TAO_Stub *stub,
00192 TAO_Operation_Details &details)
00193 {
00194 switch (this->type_)
00195 {
00196 case TAO_ONEWAY_INVOCATION:
00197 {
00198
00199 Messaging::SyncScope sync_scope;
00200
00201 bool has_synchronization = false;
00202
00203 stub->orb_core ()->call_sync_scope_hook (stub,
00204 has_synchronization,
00205 sync_scope);
00206 if (has_synchronization)
00207 details.response_flags (CORBA::Octet (sync_scope));
00208 else
00209 details.response_flags (
00210 CORBA::Octet (Messaging::SYNC_WITH_TRANSPORT));
00211 break;
00212 }
00213 case TAO_TWOWAY_INVOCATION:
00214 {
00215
00216
00217 details.response_flags (TAO_TWOWAY_RESPONSE_FLAG);
00218 break;
00219 }
00220 }
00221 }
00222
00223 Invocation_Status
00224 Invocation_Adapter::invoke_remote_i (TAO_Stub *stub,
00225 TAO_Operation_Details &details,
00226 CORBA::Object_var &effective_target,
00227 ACE_Time_Value *&max_wait_time)
00228 {
00229 (void) this->set_response_flags (stub, details);
00230
00231 CORBA::Octet const rflags = details.response_flags ();
00232 bool const block_connect =
00233 rflags != static_cast<CORBA::Octet> (Messaging::SYNC_NONE)
00234 && rflags != static_cast<CORBA::Octet> (TAO::SYNC_DELAYED_BUFFERING);
00235
00236
00237
00238 Profile_Transport_Resolver resolver (
00239 effective_target.in (),
00240 stub,
00241 block_connect);
00242
00243 resolver.resolve (max_wait_time);
00244
00245 if (TAO_debug_level)
00246 {
00247 if (max_wait_time && *max_wait_time == ACE_Time_Value::zero)
00248 ACE_DEBUG ((LM_DEBUG,
00249 ACE_TEXT ("TAO (%P|%t) - Invocation_Adapter::invoke_remote_i, ")
00250 ACE_TEXT ("max wait time consumed during transport resolution\n")));
00251 }
00252
00253
00254 if (resolver.transport ())
00255 {
00256 details.request_id (resolver.transport ()->tms ()->request_id ());
00257 }
00258
00259 switch (this->type_)
00260 {
00261 case TAO_ONEWAY_INVOCATION:
00262 {
00263 return this->invoke_oneway (details,
00264 effective_target,
00265 resolver,
00266 max_wait_time);
00267 }
00268 case TAO_TWOWAY_INVOCATION:
00269 {
00270 return this->invoke_twoway (details,
00271 effective_target,
00272 resolver,
00273 max_wait_time);
00274
00275 }
00276 }
00277 return TAO_INVOKE_FAILURE;
00278 }
00279
00280 Invocation_Status
00281 Invocation_Adapter::invoke_twoway (TAO_Operation_Details &details,
00282 CORBA::Object_var &effective_target,
00283 Profile_Transport_Resolver &r,
00284 ACE_Time_Value *&max_wait_time)
00285 {
00286
00287 if (this->mode_ != TAO_SYNCHRONOUS_INVOCATION ||
00288 this->type_ != TAO_TWOWAY_INVOCATION)
00289 {
00290 throw ::CORBA::INTERNAL (
00291 CORBA::SystemException::_tao_minor_code (
00292 TAO::VMCID,
00293 EINVAL),
00294 CORBA::COMPLETED_NO);
00295 }
00296
00297 TAO::Synch_Twoway_Invocation synch (this->target_, r, details);
00298
00299 Invocation_Status const status = synch.remote_twoway (max_wait_time);
00300
00301 if (status == TAO_INVOKE_RESTART &&
00302 (synch.reply_status () == GIOP::LOCATION_FORWARD ||
00303 synch.reply_status () == GIOP::LOCATION_FORWARD_PERM))
00304 {
00305 CORBA::Boolean const is_permanent_forward =
00306 (synch.reply_status () == GIOP::LOCATION_FORWARD_PERM);
00307
00308 effective_target = synch.steal_forwarded_reference ();
00309
00310 this->object_forwarded (effective_target,
00311 r.stub (),
00312 is_permanent_forward);
00313 }
00314
00315 return status;
00316 }
00317
00318 Invocation_Status
00319 Invocation_Adapter::invoke_oneway (TAO_Operation_Details &details,
00320 CORBA::Object_var &effective_target,
00321 Profile_Transport_Resolver &r,
00322 ACE_Time_Value *&max_wait_time)
00323 {
00324 TAO::Synch_Oneway_Invocation synch (this->target_, r, details);
00325
00326 Invocation_Status const s = synch.remote_oneway (max_wait_time);
00327
00328 if (s == TAO_INVOKE_RESTART &&
00329 (synch.reply_status () == GIOP::LOCATION_FORWARD ||
00330 synch.reply_status () == GIOP::LOCATION_FORWARD_PERM))
00331 {
00332 CORBA::Boolean const is_permanent_forward =
00333 (synch.reply_status () == GIOP::LOCATION_FORWARD_PERM);
00334
00335 effective_target = synch.steal_forwarded_reference ();
00336
00337 this->object_forwarded (effective_target,
00338 r.stub (),
00339 is_permanent_forward);
00340 }
00341
00342 return s;
00343 }
00344
00345 void
00346 Invocation_Adapter::object_forwarded (CORBA::Object_var &effective_target,
00347 TAO_Stub *stub,
00348 CORBA::Boolean permanent_forward)
00349 {
00350
00351
00352 TAO_Stub *stubobj = 0;
00353
00354 bool nil_forward_ref = false;
00355 if (CORBA::is_nil (effective_target.in ()))
00356 nil_forward_ref = true;
00357 else
00358 {
00359 stubobj =
00360 effective_target->_stubobj ();
00361
00362 if (stubobj && stubobj->base_profiles ().size () == 0)
00363 nil_forward_ref = true;
00364 }
00365
00366 if (nil_forward_ref)
00367 throw ::CORBA::TRANSIENT (
00368 CORBA::SystemException::_tao_minor_code (
00369 TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE,
00370 errno),
00371 CORBA::COMPLETED_NO);
00372
00373 if (stubobj == 0)
00374 throw ::CORBA::INTERNAL (
00375 CORBA::SystemException::_tao_minor_code (
00376 TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE,
00377 errno),
00378 CORBA::COMPLETED_NO);
00379
00380
00381 stub->add_forward_profiles (stubobj->base_profiles (), permanent_forward);
00382
00383 if (stub->next_profile () == 0)
00384 throw ::CORBA::TRANSIENT (
00385 CORBA::SystemException::_tao_minor_code (
00386 TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE,
00387 errno),
00388 CORBA::COMPLETED_NO);
00389 }
00390 }
00391
00392 TAO_END_VERSIONED_NAMESPACE_DECL