#include "tao/Invocation_Adapter.h"#include "tao/Profile_Transport_Resolver.h"#include "tao/operation_details.h"#include "tao/Stub.h"#include "tao/ORB_Core.h"#include "tao/Synch_Invocation.h"#include "tao/debug.h"#include "tao/Collocated_Invocation.h"#include "tao/Transport.h"#include "tao/Transport_Mux_Strategy.h"#include "tao/Collocation_Proxy_Broker.h"#include "tao/GIOP_Utils.h"#include "tao/TAOC.h"#include "tao/SystemException.h"#include "ace/Service_Config.h"
Go to the source code of this file.
Functions | |
| ACE_RCSID (tao, Invocation_Adapter,"$Id: Invocation_Adapter.cpp 85951 2009-07-09 13:11:43Z sma $") 1 namespace TAO | |
| ACE_RCSID | ( | tao | , | |
| Invocation_Adapter | , | |||
| "$Id: Invocation_Adapter.cpp 85951 2009-07-09 13:11:43Z sma $" | ||||
| ) |
Definition at line 24 of file Invocation_Adapter.cpp.
00026 : 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 // Should stub object be refcounted here? 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 // The invocation has got to be within the context of the 00057 // corresponding ORB's configuration. Otherwise things like 00058 // timeout hooks, etc may not work as expected. Especially if 00059 // there are multiple ORB instances in the process, each with its 00060 // own, local configuration. 00061 ACE_Service_Config_Guard scg (stub->orb_core ()->configuration ()); 00062 00063 // Cache the target to a local variable. 00064 CORBA::Object_var effective_target = 00065 CORBA::Object::_duplicate (this->target_); 00066 00067 // Initial state 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 // Default we go to remote 00079 Collocation_Strategy strat = TAO_CS_REMOTE_STRATEGY; 00080 00081 // If we have a collocated proxy broker we look if we maybe 00082 // can use a collocated invocation. Similarly, if the 00083 // target object reference contains a pointer to a servant, 00084 // the object reference also refers to a collocated object. 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 // To make a collocated call we must have a collocated proxy broker, the 00158 // invoke_i() will make sure that we only come here when we have one 00159 ACE_ASSERT (cpb_ != 0 00160 || (strat == TAO_CS_THRU_POA_STRATEGY 00161 && effective_target->_servant () != 0)); 00162 00163 // Initial state 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 // Grab the syncscope policy from the ORB. 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 // @@note: Need to change this to something better. Too many 00216 // hash defines meaning the same things. 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 // Create the resolver which will pick (or create) for us a 00237 // transport and a profile from the effective_target. 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 // Update the request id now that we have a transport 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 // Simple sanity check 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 // The object pointer has to be changed to a TAO_Stub pointer 00351 // in order to obtain the profiles. 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 // Reset the profile in the stubs 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 } // End namespace TAO
1.6.1