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 81632 2008-05-07 09:19:05Z vzykov $")
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
00070 while (status == TAO_INVOKE_START || status == TAO_INVOKE_RESTART)
00071 {
00072
00073 Collocation_Strategy strat = TAO_CS_REMOTE_STRATEGY;
00074
00075
00076
00077
00078
00079 if (cpb_ != 0 || effective_target->_servant () != 0)
00080 {
00081 strat = TAO_ORB_Core::collocation_strategy (effective_target.in ());
00082 }
00083
00084 if (strat == TAO_CS_REMOTE_STRATEGY || strat == TAO_CS_LAST)
00085 {
00086 ACE_Time_Value *max_wait_time = 0;
00087 status =
00088 this->invoke_remote_i (stub,
00089 details,
00090 effective_target,
00091 max_wait_time);
00092 }
00093 else
00094 {
00095 if (strat == TAO_CS_THRU_POA_STRATEGY)
00096 {
00097 (void) this->set_response_flags (stub, details);
00098 }
00099
00100 status =
00101 this->invoke_collocated_i (stub,
00102 details,
00103 effective_target,
00104 strat);
00105 }
00106
00107 if (status == TAO_INVOKE_RESTART)
00108 {
00109 details.reset_request_service_info ();
00110 details.reset_reply_service_info ();
00111
00112 if (TAO_debug_level > 2)
00113 {
00114 ACE_DEBUG ((LM_DEBUG,
00115 "TAO (%P|%t) - Invocation_Adapter::invoke_i, "
00116 "handling forwarded locations \n"));
00117 }
00118 }
00119 }
00120 }
00121
00122 bool
00123 Invocation_Adapter::get_timeout (TAO_Stub *stub, ACE_Time_Value &timeout)
00124 {
00125 bool has_timeout = false;
00126 this->target_->orb_core ()->call_timeout_hook (stub, has_timeout, timeout);
00127
00128 return has_timeout;
00129 }
00130
00131 TAO_Stub *
00132 Invocation_Adapter::get_stub (void) const
00133 {
00134 TAO_Stub * const stub = this->target_->_stubobj ();
00135
00136 if (stub == 0)
00137 throw ::CORBA::INTERNAL (
00138 CORBA::SystemException::_tao_minor_code (
00139 TAO::VMCID,
00140 EINVAL),
00141 CORBA::COMPLETED_NO);
00142
00143 return stub;
00144 }
00145
00146 Invocation_Status
00147 Invocation_Adapter::invoke_collocated_i (TAO_Stub *stub,
00148 TAO_Operation_Details &details,
00149 CORBA::Object_var &effective_target,
00150 Collocation_Strategy strat)
00151 {
00152
00153
00154 ACE_ASSERT (cpb_ != 0
00155 || (strat == TAO_CS_THRU_POA_STRATEGY
00156 && effective_target->_servant () != 0));
00157
00158
00159 TAO::Invocation_Status status = TAO_INVOKE_START;
00160
00161 Collocated_Invocation coll_inv (this->target_,
00162 effective_target.in (),
00163 stub,
00164 details,
00165 this->type_ == TAO_TWOWAY_INVOCATION);
00166
00167 status = coll_inv.invoke (this->cpb_, strat);
00168
00169 if (status == TAO_INVOKE_RESTART &&
00170 (coll_inv.reply_status () == GIOP::LOCATION_FORWARD ||
00171 coll_inv.reply_status () == GIOP::LOCATION_FORWARD_PERM))
00172 {
00173 CORBA::Boolean const is_permanent_forward =
00174 (coll_inv.reply_status () == GIOP::LOCATION_FORWARD_PERM);
00175
00176 effective_target = coll_inv.steal_forwarded_reference ();
00177
00178 this->object_forwarded (effective_target, stub, is_permanent_forward);
00179 }
00180
00181 return status;
00182 }
00183
00184 void
00185 Invocation_Adapter::set_response_flags (
00186 TAO_Stub *stub,
00187 TAO_Operation_Details &details)
00188 {
00189 switch (this->type_)
00190 {
00191 case TAO_ONEWAY_INVOCATION:
00192 {
00193
00194 Messaging::SyncScope sync_scope;
00195
00196 bool has_synchronization = false;
00197
00198 stub->orb_core ()->call_sync_scope_hook (stub,
00199 has_synchronization,
00200 sync_scope);
00201 if (has_synchronization)
00202 details.response_flags (CORBA::Octet (sync_scope));
00203 else
00204 details.response_flags (
00205 CORBA::Octet (Messaging::SYNC_WITH_TRANSPORT));
00206 break;
00207 }
00208 case TAO_TWOWAY_INVOCATION:
00209 {
00210
00211
00212 details.response_flags (TAO_TWOWAY_RESPONSE_FLAG);
00213 break;
00214 }
00215 }
00216 }
00217
00218 Invocation_Status
00219 Invocation_Adapter::invoke_remote_i (TAO_Stub *stub,
00220 TAO_Operation_Details &details,
00221 CORBA::Object_var &effective_target,
00222 ACE_Time_Value *&max_wait_time)
00223 {
00224 ACE_Time_Value tmp_wait_time;
00225 bool const is_timeout = this->get_timeout (stub, tmp_wait_time);
00226
00227 if (is_timeout)
00228 max_wait_time = &tmp_wait_time;
00229
00230 (void) this->set_response_flags (stub, details);
00231
00232 CORBA::Octet const rflags = details.response_flags ();
00233 bool const block_connect =
00234 rflags != static_cast<CORBA::Octet> (Messaging::SYNC_NONE)
00235 && rflags != static_cast<CORBA::Octet> (TAO::SYNC_DELAYED_BUFFERING);
00236
00237
00238
00239 Profile_Transport_Resolver resolver (
00240 effective_target.in (),
00241 stub,
00242 block_connect);
00243
00244 resolver.resolve (max_wait_time);
00245
00246 if (TAO_debug_level)
00247 {
00248 if (is_timeout && *max_wait_time == ACE_Time_Value::zero)
00249 ACE_DEBUG ((LM_DEBUG,
00250 ACE_TEXT ("(%P|%t)Invocation_Adapter::invoke_remote_i: ")
00251 ACE_TEXT ("max wait time consumed during transport resolution\n")));
00252 }
00253
00254
00255 if (resolver.transport ())
00256 {
00257 details.request_id (resolver.transport ()->tms ()->request_id ());
00258 }
00259
00260 switch (this->type_)
00261 {
00262 case TAO_ONEWAY_INVOCATION:
00263 {
00264 return this->invoke_oneway (details,
00265 effective_target,
00266 resolver,
00267 max_wait_time);
00268 }
00269 case TAO_TWOWAY_INVOCATION:
00270 {
00271 return this->invoke_twoway (details,
00272 effective_target,
00273 resolver,
00274 max_wait_time);
00275
00276 }
00277 }
00278 return TAO_INVOKE_FAILURE;
00279 }
00280
00281 Invocation_Status
00282 Invocation_Adapter::invoke_twoway (TAO_Operation_Details &details,
00283 CORBA::Object_var &effective_target,
00284 Profile_Transport_Resolver &r,
00285 ACE_Time_Value *&max_wait_time)
00286 {
00287
00288 if (this->mode_ != TAO_SYNCHRONOUS_INVOCATION ||
00289 this->type_ != TAO_TWOWAY_INVOCATION)
00290 {
00291 throw ::CORBA::INTERNAL (
00292 CORBA::SystemException::_tao_minor_code (
00293 TAO::VMCID,
00294 EINVAL),
00295 CORBA::COMPLETED_NO);
00296 }
00297
00298 TAO::Synch_Twoway_Invocation synch (this->target_, r, details);
00299
00300 Invocation_Status const status = synch.remote_twoway (max_wait_time);
00301
00302 if (status == TAO_INVOKE_RESTART &&
00303 (synch.reply_status () == GIOP::LOCATION_FORWARD ||
00304 synch.reply_status () == GIOP::LOCATION_FORWARD_PERM))
00305 {
00306 CORBA::Boolean const is_permanent_forward =
00307 (synch.reply_status () == GIOP::LOCATION_FORWARD_PERM);
00308
00309 effective_target = synch.steal_forwarded_reference ();
00310
00311 this->object_forwarded (effective_target,
00312 r.stub (),
00313 is_permanent_forward);
00314 }
00315
00316 return status;
00317 }
00318
00319 Invocation_Status
00320 Invocation_Adapter::invoke_oneway (TAO_Operation_Details &details,
00321 CORBA::Object_var &effective_target,
00322 Profile_Transport_Resolver &r,
00323 ACE_Time_Value *&max_wait_time)
00324 {
00325 TAO::Synch_Oneway_Invocation synch (this->target_, r, details);
00326
00327 Invocation_Status const s = synch.remote_oneway (max_wait_time);
00328
00329 if (s == TAO_INVOKE_RESTART &&
00330 (synch.reply_status () == GIOP::LOCATION_FORWARD ||
00331 synch.reply_status () == GIOP::LOCATION_FORWARD_PERM))
00332 {
00333 CORBA::Boolean const is_permanent_forward =
00334 (synch.reply_status () == GIOP::LOCATION_FORWARD_PERM);
00335
00336 effective_target = synch.steal_forwarded_reference ();
00337
00338 this->object_forwarded (effective_target,
00339 r.stub (),
00340 is_permanent_forward);
00341 }
00342
00343 return s;
00344 }
00345
00346 void
00347 Invocation_Adapter::object_forwarded (CORBA::Object_var &effective_target,
00348 TAO_Stub *stub,
00349 CORBA::Boolean permanent_forward)
00350 {
00351
00352
00353 TAO_Stub *stubobj = 0;
00354
00355 bool nil_forward_ref = false;
00356 if (CORBA::is_nil (effective_target.in ()))
00357 nil_forward_ref = true;
00358 else
00359 {
00360 stubobj =
00361 effective_target->_stubobj ();
00362
00363 if (stubobj && stubobj->base_profiles ().size () == 0)
00364 nil_forward_ref = true;
00365 }
00366
00367 if (nil_forward_ref)
00368 throw ::CORBA::TRANSIENT (
00369 CORBA::SystemException::_tao_minor_code (
00370 TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE,
00371 errno),
00372 CORBA::COMPLETED_NO);
00373
00374 if (stubobj == 0)
00375 throw ::CORBA::INTERNAL (
00376 CORBA::SystemException::_tao_minor_code (
00377 TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE,
00378 errno),
00379 CORBA::COMPLETED_NO);
00380
00381
00382 stub->add_forward_profiles (stubobj->base_profiles (), permanent_forward);
00383
00384 if (stub->next_profile () == 0)
00385 throw ::CORBA::TRANSIENT (
00386 CORBA::SystemException::_tao_minor_code (
00387 TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE,
00388 errno),
00389 CORBA::COMPLETED_NO);
00390 }
00391 }
00392
00393 TAO_END_VERSIONED_NAMESPACE_DECL