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