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