#include <Synch_Invocation.h>
Inheritance diagram for TAO::Synch_Twoway_Invocation:
Public Member Functions | |
Synch_Twoway_Invocation (CORBA::Object_ptr otarget, Profile_Transport_Resolver &resolver, TAO_Operation_Details &detail, bool response_expected=true) | |
Constructor used by TAO::Invocation_Adapter. | |
Invocation_Status | remote_twoway (ACE_Time_Value *max_wait_time) throw (CORBA::Exception) |
Protected Member Functions | |
virtual Invocation_Status | handle_user_exception (TAO_InputCDR &cdr) throw (CORBA::Exception) |
Invocation_Status | location_forward (TAO_InputCDR &cdr) throw (CORBA::SystemException) |
Helper method used to handle location forwarded replies. | |
Invocation_Status | handle_system_exception (TAO_InputCDR &cdr) throw (CORBA::SystemException) |
Invocation_Status | wait_for_reply (ACE_Time_Value *max_wait_time, TAO_Synch_Reply_Dispatcher &rd, TAO_Bind_Dispatcher_Guard &bd) throw (CORBA::SystemException) |
As the name suggests waits for a reply from the remote ORB. | |
Private Member Functions | |
Invocation_Status | check_reply_status (TAO_Synch_Reply_Dispatcher &rd) |
An object of this type is created by TAO::Invocation_Adapter and invokes a method on this class. The method takes care of creating and sending a request, waiting for a reply and demarshalling the reply for the client.
Definition at line 52 of file Synch_Invocation.h.
|
Constructor used by TAO::Invocation_Adapter.
Definition at line 40 of file Synch_Invocation.cpp. References CORBA::Object_ptr.
00045 : Remote_Invocation (otarget, 00046 resolver, 00047 detail, 00048 response_expected) 00049 { 00050 } |
|
This method returns an exception when there is an error. Definition at line 368 of file Synch_Invocation.cpp. References ACE_CHECK_RETURN, ACE_DEBUG, ACE_ENV_ARG_PARAMETER, ACE_THROW_RETURN, TAO_Transport::assign_translators(), TAO_Operation_Details::demarshal_args(), handle_system_exception(), handle_user_exception(), TAO_Pseudo_Var_T< T >::in(), TAO::Invocation_Status, TAO_ORB_Core::is_permanent_forward_condition(), LM_DEBUG, location_forward(), TAO::Invocation_Base::orb_core(), TAO::Profile_Transport_Resolver::profile(), ACE_InputCDR::read_short(), TAO::Invocation_Base::request_service_context(), TAO::Reply_Guard::set_status(), TAO_debug_level, TAO::TAO_INVOKE_FAILURE, TAO::TAO_INVOKE_RESTART, TAO::TAO_INVOKE_SUCCESS, TAO_PLUGGABLE_MESSAGE_LOCATION_FORWARD, TAO_PLUGGABLE_MESSAGE_LOCATION_FORWARD_PERM, TAO_PLUGGABLE_MESSAGE_NEEDS_ADDRESSING_MODE, TAO_PLUGGABLE_MESSAGE_NO_EXCEPTION, TAO_PLUGGABLE_MESSAGE_SYSTEM_EXCEPTION, TAO_PLUGGABLE_MESSAGE_USER_EXCEPTION, and TAO::Profile_Transport_Resolver::transport().
00370 { 00371 /* 00372 * Precondition: We probably got a reply. <ACE_Thread::self> is 00373 * checking the status of the reply 00374 * 00375 * Postcondition: Any error while reading the reply is marked by 00376 * raising an exception. LOCATION_FORWARDED replies are marked by 00377 * returning a restart since that is what needed to be done by the 00378 * callee. 00379 */ 00380 TAO_InputCDR &cdr = 00381 rd.reply_cdr (); 00382 00383 // Set the translators 00384 this->resolver_.transport ()->assign_translators (&cdr, 0); 00385 00386 // At this point it can be assumed that the GIOP/whatever protocol 00387 // header and the reply header are already handled. Further it 00388 // can be assumed that the reply body contains the details 00389 // required for further processing. All the other details should 00390 // have been handled in the reply dispatcher/protocol framework. 00391 switch (rd.reply_status ()) 00392 { 00393 case TAO_PLUGGABLE_MESSAGE_NO_EXCEPTION: 00394 { 00395 Reply_Guard mon (this, 00396 TAO_INVOKE_FAILURE); 00397 if (this->details_.demarshal_args (cdr) == false) 00398 { 00399 ACE_THROW_RETURN (CORBA::MARSHAL (), 00400 TAO_INVOKE_FAILURE); 00401 } 00402 00403 mon.set_status (TAO_INVOKE_SUCCESS); 00404 } 00405 break; 00406 case TAO_PLUGGABLE_MESSAGE_LOCATION_FORWARD: 00407 return this->location_forward (cdr 00408 ACE_ENV_ARG_PARAMETER); 00409 case TAO_PLUGGABLE_MESSAGE_LOCATION_FORWARD_PERM: 00410 { 00411 // Unmarshal the location forward object and set the 00412 // variable this->forward_to_. 00413 const Invocation_Status s 00414 = this->location_forward (cdr 00415 ACE_ENV_ARG_PARAMETER); 00416 if (s != TAO_INVOKE_FAILURE) 00417 { 00418 // de-marshalling of permanent object reference was successfull 00419 const CORBA::Boolean permanent_forward_condition = 00420 this->orb_core ()->is_permanent_forward_condition 00421 (this->forwarded_to_.in (), 00422 this->request_service_context ()); 00423 00424 if (!permanent_forward_condition) 00425 { 00426 // permanent condition not given 00427 if (TAO_debug_level > 3) 00428 ACE_DEBUG ((LM_DEBUG, 00429 "TAO (%P|%t) - Synch_Twoway_Invocation::" 00430 "check_reply_status: unexpected LOCATION_FORWARD_PERM reply\n")); 00431 00432 ACE_THROW_RETURN (CORBA::INTERNAL (0, CORBA::COMPLETED_NO), 00433 TAO_INVOKE_FAILURE); 00434 } 00435 } 00436 00437 return s; 00438 } 00439 case TAO_PLUGGABLE_MESSAGE_USER_EXCEPTION: 00440 return this->handle_user_exception (cdr 00441 ACE_ENV_ARG_PARAMETER); 00442 case TAO_PLUGGABLE_MESSAGE_SYSTEM_EXCEPTION: 00443 return this->handle_system_exception (cdr 00444 ACE_ENV_ARG_PARAMETER); 00445 00446 case TAO_PLUGGABLE_MESSAGE_NEEDS_ADDRESSING_MODE: 00447 { 00448 Reply_Guard mon (this, 00449 TAO_INVOKE_FAILURE); 00450 // We have received a message with a request to change the 00451 // addressing mode. First let us read the mode that the 00452 // server/agent asks for. 00453 CORBA::Short addr_mode = 0; 00454 00455 if (cdr.read_short (addr_mode) == 0) 00456 { 00457 // Could not demarshal the addressing disposition, raise an local 00458 // CORBA::MARSHAL 00459 ACE_THROW_RETURN (CORBA::MARSHAL (0, 00460 CORBA::COMPLETED_MAYBE), 00461 TAO_INVOKE_FAILURE); 00462 } 00463 00464 // Now set this addressing mode in the profile, so that 00465 // the next invocation need not go through this. 00466 this->resolver_.profile ()->addressing_mode (addr_mode 00467 ACE_ENV_ARG_PARAMETER); 00468 ACE_CHECK_RETURN (TAO_INVOKE_FAILURE); 00469 00470 mon.set_status (TAO_INVOKE_RESTART); 00471 00472 // Now restart the invocation 00473 return TAO_INVOKE_RESTART; 00474 } 00475 } 00476 return TAO_INVOKE_SUCCESS; 00477 } |
|
Helper method used to handle system exceptions from the remote objects. There has been a unanimous view that this is not the right way to do things. But a need to be compliant is forcing us into this.
Definition at line 575 of file Synch_Invocation.cpp. References ACE_CHECK_RETURN, ACE_DEBUG, ACE_ENV_ARG_PARAMETER, ACE_ENV_RAISE, ACE_NEW_RETURN, ACE_THROW_RETURN, CORBA::SystemException::completed(), TAO::create_system_exception(), TAO::String_var< charT >::in(), TAO::String_var< charT >::inout(), TAO::Invocation_Status, LM_DEBUG, CORBA::SystemException::minor(), TAO::Reply_Guard::set_status(), CORBA::String_var, TAO_debug_level, TAO::TAO_INVOKE_FAILURE, TAO::TAO_INVOKE_RESTART, and TAO::TAO_INVOKE_SYSTEM_EXCEPTION. Referenced by check_reply_status().
00578 { 00579 Reply_Guard mon (this, TAO_INVOKE_FAILURE); 00580 00581 if (TAO_debug_level > 3) 00582 ACE_DEBUG ((LM_DEBUG, 00583 "TAO (%P|%t) - Synch_Twoway_Invocation::" 00584 "handle_system_exception \n")); 00585 00586 CORBA::String_var type_id; 00587 00588 if ((cdr >> type_id.inout ()) == 0) 00589 { 00590 // Could not demarshal the exception id, raise an local 00591 // CORBA::MARSHAL 00592 ACE_THROW_RETURN (CORBA::MARSHAL (0, 00593 CORBA::COMPLETED_MAYBE), 00594 TAO_INVOKE_FAILURE); 00595 } 00596 00597 CORBA::ULong minor = 0; 00598 CORBA::ULong completion = 0; 00599 00600 if ((cdr >> minor) == 0 00601 || (cdr >> completion) == 0) 00602 { 00603 ACE_THROW_RETURN (CORBA::MARSHAL (0, 00604 CORBA::COMPLETED_MAYBE), 00605 TAO_INVOKE_FAILURE); 00606 } 00607 00608 // Special handling for non-fatal system exceptions. 00609 // 00610 // Note that we are careful to retain "at most once" semantics. 00611 if ((ACE_OS_String::strcmp (type_id.in (), 00612 "IDL:omg.org/CORBA/TRANSIENT:1.0") == 0 || 00613 ACE_OS_String::strcmp (type_id.in (), 00614 "IDL:omg.org/CORBA/OBJ_ADAPTER:1.0") == 0 || 00615 ACE_OS_String::strcmp (type_id.in (), 00616 "IDL:omg.org/CORBA/NO_RESPONSE:1.0") == 0 || 00617 ACE_OS_String::strcmp (type_id.in (), 00618 "IDL:omg.org/CORBA/COMM_FAILURE:1.0") == 0) && 00619 (CORBA::CompletionStatus) completion != CORBA::COMPLETED_YES) 00620 { 00621 { 00622 // Start the special case for FTCORBA. 00623 /** 00624 * There has been a unanimous view that this is not the 00625 * right way to do things. But a need to be compliant is 00626 * forcing us into this. 00627 */ 00628 const Invocation_Status s = 00629 this->orb_core ()->service_raise_transient_failure ( 00630 this->details_.request_service_context ().service_info (), 00631 this->resolver_.profile () 00632 ACE_ENV_ARG_PARAMETER); 00633 ACE_CHECK_RETURN (TAO_INVOKE_FAILURE); 00634 00635 if (s == TAO_INVOKE_RESTART) 00636 return s; 00637 } 00638 00639 // Attempt profile retry. 00640 /** 00641 * @note A location forwarding loop may occur where a client 00642 * is bounced from the original target to the forwarded 00643 * target and back if the application is not equipped to 00644 * handle retries of previously called targets. TAO may 00645 * be able to help in this case but it ultimately ends 00646 * up being an application issue. 00647 */ 00648 if (this->resolver_.stub ()->next_profile_retry ()) 00649 { 00650 return TAO_INVOKE_RESTART; 00651 } 00652 00653 // Fall through and raise an exception. 00654 } 00655 00656 CORBA::SystemException *ex = 00657 TAO::create_system_exception (type_id.in ()); 00658 00659 if (ex == 0) 00660 { 00661 // @@ We should raise a CORBA::NO_MEMORY, but we ran out 00662 // of memory already. We need a pre-allocated, TSS, 00663 // CORBA::NO_MEMORY instance 00664 ACE_NEW_RETURN (ex, 00665 CORBA::UNKNOWN, 00666 TAO_INVOKE_FAILURE); 00667 } 00668 00669 #if defined (TAO_HAS_EXCEPTIONS) 00670 // Without this, the call to create_system_exception() above 00671 // causes a memory leak. On platforms without native exceptions, 00672 // the CORBA::Environment class manages the memory. 00673 auto_ptr<CORBA::SystemException> safety (ex); 00674 #endif 00675 00676 ex->minor (minor); 00677 ex->completed (CORBA::CompletionStatus (completion)); 00678 00679 if (TAO_debug_level > 4) 00680 ACE_DEBUG ((LM_DEBUG, 00681 "TAO (%P|%t) - Synch_Twoway_Invocation::" 00682 "handle_system_exception, about to raise\n")); 00683 00684 mon.set_status (TAO_INVOKE_SYSTEM_EXCEPTION); 00685 00686 // Raise the exception. 00687 ACE_ENV_RAISE (ex); 00688 00689 return TAO_INVOKE_SYSTEM_EXCEPTION; 00690 } |
|
This method is selectively made virtual, so that inherited classes can overload the user exception handling type. For example the DII needs a totally different method of user exception exception handling Definition at line 514 of file Synch_Invocation.cpp. References CORBA::Exception::_raise(), CORBA::Exception::_tao_decode(), ACE_CHECK_RETURN, ACE_DEBUG, ACE_ENV_ARG_PARAMETER, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, ACE_THROW_RETURN, ACE_TRY_ENV, TAO::String_var< charT >::in(), TAO::String_var< charT >::inout(), LM_DEBUG, TAO::Reply_Guard::set_status(), CORBA::String_var, TAO_debug_level, TAO::TAO_INVOKE_FAILURE, and TAO::TAO_INVOKE_USER_EXCEPTION. Referenced by check_reply_status().
00517 { 00518 Reply_Guard mon (this, 00519 TAO_INVOKE_FAILURE); 00520 00521 if (TAO_debug_level > 3) 00522 ACE_DEBUG ((LM_DEBUG, 00523 "TAO (%P|%t) - Synch_Twoway_Invocation::" 00524 "handle_user_exception \n")); 00525 00526 // Pull the exception from the stream. 00527 CORBA::String_var buf; 00528 00529 if ((cdr >> buf.inout ()) == 0) 00530 { 00531 // Could not demarshal the exception id, raise an local 00532 // CORBA::MARSHAL 00533 ACE_THROW_RETURN (CORBA::MARSHAL (0, 00534 CORBA::COMPLETED_MAYBE), 00535 TAO_INVOKE_FAILURE); 00536 } 00537 00538 CORBA::Exception *exception = 00539 this->details_.corba_exception (buf.in () 00540 ACE_ENV_ARG_PARAMETER); 00541 ACE_CHECK_RETURN (TAO_INVOKE_FAILURE); 00542 00543 exception->_tao_decode (cdr 00544 ACE_ENV_ARG_PARAMETER); 00545 ACE_CHECK_RETURN (TAO_INVOKE_FAILURE); 00546 00547 if (TAO_debug_level > 5) 00548 { 00549 ACE_DEBUG ((LM_DEBUG, 00550 ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::") 00551 ACE_TEXT ("handle_user_exception - ") 00552 ACE_TEXT ("raising exception %s\n"), 00553 ACE_TEXT_CHAR_TO_TCHAR (buf.in ()))); 00554 } 00555 00556 mon.set_status (TAO_INVOKE_USER_EXCEPTION); 00557 00558 #if defined (TAO_HAS_EXCEPTIONS) 00559 // If we have native exceptions, we must manage the memory allocated 00560 // by the call above to alloc(). Otherwise the Environment class 00561 // manages the memory. 00562 auto_ptr<CORBA::Exception> safety (exception); 00563 00564 // Direct throw because we don't have the ACE_TRY_ENV. 00565 exception->_raise (); 00566 #else 00567 // We can not use ACE_THROW here. 00568 ACE_TRY_ENV.exception (exception); 00569 #endif 00570 00571 return TAO_INVOKE_USER_EXCEPTION; 00572 } |
|
Helper method used to handle location forwarded replies.
Definition at line 480 of file Synch_Invocation.cpp. References ACE_DEBUG, ACE_TEXT, ACE_THROW_RETURN, TAO_Pseudo_Var_T< T >::in(), LM_DEBUG, CORBA::Object_var, TAO::Reply_Guard::set_status(), TAO_debug_level, TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE, TAO::TAO_INVOKE_FAILURE, and TAO::TAO_INVOKE_RESTART. Referenced by TAO::LocateRequest_Invocation::check_reply(), and check_reply_status().
00483 { 00484 Reply_Guard mon (this, 00485 TAO_INVOKE_FAILURE); 00486 00487 if (TAO_debug_level > 3) 00488 { 00489 ACE_DEBUG ((LM_DEBUG, 00490 ACE_TEXT ("TAO (%P|%t) - Synch_Twoway_Invocation::location_forward ") 00491 ACE_TEXT ("being handled \n"))); 00492 } 00493 00494 CORBA::Object_var fwd; 00495 00496 if ((inp_stream >> fwd) == 0) 00497 { 00498 ACE_THROW_RETURN (CORBA::MARSHAL ( 00499 CORBA::SystemException::_tao_minor_code ( 00500 TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE, 00501 errno), 00502 CORBA::COMPLETED_NO), 00503 TAO_INVOKE_FAILURE); 00504 } 00505 00506 this->forwarded_reference (fwd.in ()); 00507 00508 mon.set_status (TAO_INVOKE_RESTART); 00509 00510 return TAO_INVOKE_RESTART; 00511 } |
|
There is a exception declaration in this method which ensures that the exceptions propogated by the remote objects are converted a CORBA exceptions for the clients. This method does a bunch of things necessary to create and send the invocation. This method is also nerve centre for the interceptor invocation points. Definition at line 53 of file Synch_Invocation.cpp. References ACE_ANY_EXCEPTION, ACE_CATCHALL, ACE_CATCHANY, ACE_CHECK_RETURN, ACE_ENDTRY, ACE_ENV_ARG_PARAMETER, ACE_ENV_SINGLE_ARG_PARAMETER, ACE_RE_THROW, ACE_THROW_RETURN, ACE_TRY, ACE_TRY_CHECK, TAO::Invocation_Status, TAO_OutputCDR::message_attributes(), PortableInterceptor::ReplyStatus, TAO_Bind_Dispatcher_Guard::status(), TAO::TAO_INVOKE_FAILURE, TAO::TAO_INVOKE_RESTART, TAO::TAO_INVOKE_SUCCESS, and ACE_Countdown_Time::update(). Referenced by TAO::Invocation_Adapter::invoke_twoway().
00056 { 00057 ACE_Countdown_Time countdown (max_wait_time); 00058 00059 TAO_Synch_Reply_Dispatcher rd (this->resolver_.stub ()->orb_core (), 00060 this->details_.reply_service_info ()); 00061 00062 TAO_Target_Specification tspec; 00063 this->init_target_spec (tspec ACE_ENV_ARG_PARAMETER); 00064 ACE_CHECK_RETURN (TAO_INVOKE_FAILURE); 00065 00066 Invocation_Status s = TAO_INVOKE_FAILURE; 00067 00068 #if TAO_HAS_INTERCEPTORS == 1 00069 // Start the interception point here.. 00070 s = 00071 this->send_request_interception (ACE_ENV_SINGLE_ARG_PARAMETER); 00072 ACE_CHECK_RETURN (TAO_INVOKE_FAILURE); 00073 00074 if (s != TAO_INVOKE_SUCCESS) 00075 return s; 00076 #endif /*TAO_HAS_INTERCEPTORS */ 00077 00078 // We have started the interception flow. We need to call the 00079 // ending interception flow if things go wrong. The purpose of the 00080 // try block is to do just this. 00081 ACE_TRY 00082 { 00083 TAO_OutputCDR &cdr = this->resolver_.transport ()->out_stream (); 00084 00085 cdr.message_attributes (this->details_.request_id (), 00086 this->resolver_.stub (), 00087 TAO_Transport::TAO_TWOWAY_REQUEST, 00088 max_wait_time); 00089 00090 this->write_header (tspec, 00091 cdr 00092 ACE_ENV_ARG_PARAMETER); 00093 ACE_TRY_CHECK; 00094 00095 this->marshal_data (cdr 00096 ACE_ENV_ARG_PARAMETER); 00097 ACE_TRY_CHECK; 00098 00099 // Register a reply dispatcher for this invocation. Use the 00100 // preallocated reply dispatcher. 00101 TAO_Bind_Dispatcher_Guard dispatch_guard ( 00102 this->details_.request_id (), 00103 &rd, 00104 this->resolver_.transport ()->tms ()); 00105 00106 if (dispatch_guard.status () != 0) 00107 { 00108 // @@ What is the right way to handle this error? Why should 00109 // we close the connection? 00110 this->resolver_.transport ()->close_connection (); 00111 00112 ACE_THROW_RETURN ( 00113 CORBA::INTERNAL ( 00114 0, 00115 CORBA::COMPLETED_NO), 00116 s); 00117 } 00118 00119 countdown.update (); 00120 00121 s = this->send_message (cdr, 00122 TAO_Transport::TAO_TWOWAY_REQUEST, 00123 max_wait_time 00124 ACE_ENV_ARG_PARAMETER); 00125 ACE_TRY_CHECK; 00126 00127 #if TAO_HAS_INTERCEPTORS == 1 00128 // @@NOTE: Too much code repetition. 00129 // If the above call returns a restart due to connection 00130 // failure then call the receive_other interception point 00131 // before we leave. 00132 if (s == TAO_INVOKE_RESTART) 00133 { 00134 const Invocation_Status tmp = 00135 this->receive_other_interception (ACE_ENV_SINGLE_ARG_PARAMETER); 00136 ACE_TRY_CHECK; 00137 00138 if (tmp != TAO_INVOKE_SUCCESS) 00139 s = tmp; 00140 } 00141 #endif /*TAO_HAS_INTERCEPTORS */ 00142 00143 if (s != TAO_INVOKE_SUCCESS) 00144 return s; 00145 00146 countdown.update (); 00147 00148 // For some strategies one may want to release the transport 00149 // back to cache. If the idling is successfull let the 00150 // resolver about that. 00151 if (this->resolver_.transport ()->idle_after_send ()) 00152 this->resolver_.transport_released (); 00153 00154 // @@ In all MT environments, there's a cancellation point lurking 00155 // here; need to investigate. Client threads would frequently be 00156 // canceled sometime during recv_request ... the correct action to 00157 // take on being canceled is to issue a CancelRequest message to the 00158 // server and then imediately let other client-side cancellation 00159 // handlers do their jobs. 00160 // 00161 // In C++, that basically means to unwind the stack using almost 00162 // normal procedures: all destructors should fire, and some "catch" 00163 // blocks should probably be able to handle things like releasing 00164 // pointers. (Without unwinding the C++ stack, resources that must 00165 // be freed by thread cancellation won't be freed, and the process 00166 // won't continue to function correctly.) The tricky part is that 00167 // according to POSIX, all C stack frames must also have their 00168 // (explicitly coded) handlers called. We assume a POSIX.1c/C/C++ 00169 // environment. 00170 00171 s = 00172 this->wait_for_reply (max_wait_time, 00173 rd, 00174 dispatch_guard 00175 ACE_ENV_ARG_PARAMETER); 00176 ACE_TRY_CHECK; 00177 00178 #if TAO_HAS_INTERCEPTORS == 1 00179 if (s == TAO_INVOKE_RESTART) 00180 { 00181 Invocation_Status tmp = 00182 this->receive_other_interception (ACE_ENV_SINGLE_ARG_PARAMETER); 00183 ACE_TRY_CHECK; 00184 00185 // Push the latest values for the return.. 00186 if (tmp != TAO_INVOKE_SUCCESS) 00187 s = tmp; 00188 } 00189 #endif /*TAO_HAS_INTERCEPTORS */ 00190 00191 if (s != TAO_INVOKE_SUCCESS) 00192 return s; 00193 00194 // What happens when the above call returns an error through 00195 // the return value? That would be bogus as per the contract 00196 // in the interface. The call violated the contract 00197 00198 s = this->check_reply_status (rd 00199 ACE_ENV_ARG_PARAMETER); 00200 ACE_TRY_CHECK; 00201 00202 // For some strategies one may want to release the transport 00203 // back to cache after receiving the reply. 00204 if (this->resolver_.transport ()->idle_after_reply ()) 00205 this->resolver_.transport_released (); 00206 00207 #if TAO_HAS_INTERCEPTORS == 1 00208 Invocation_Status tmp = TAO_INVOKE_FAILURE; 00209 if (s == TAO_INVOKE_RESTART) 00210 { 00211 tmp = 00212 this->receive_other_interception (ACE_ENV_SINGLE_ARG_PARAMETER); 00213 ACE_TRY_CHECK; 00214 } 00215 else if (s == TAO_INVOKE_SUCCESS) 00216 { 00217 tmp = 00218 this->receive_reply_interception (ACE_ENV_SINGLE_ARG_PARAMETER); 00219 ACE_TRY_CHECK; 00220 } 00221 if (tmp != TAO_INVOKE_SUCCESS) 00222 s = tmp; 00223 #endif /*TAO_HAS_INTERCEPTORS */ 00224 00225 if (s != TAO_INVOKE_SUCCESS) 00226 return s; 00227 } 00228 ACE_CATCHANY 00229 { 00230 #if TAO_HAS_INTERCEPTORS == 1 00231 const PortableInterceptor::ReplyStatus status = 00232 this->handle_any_exception (&ACE_ANY_EXCEPTION 00233 ACE_ENV_ARG_PARAMETER); 00234 ACE_TRY_CHECK; 00235 00236 if (status == PortableInterceptor::LOCATION_FORWARD || 00237 status == PortableInterceptor::TRANSPORT_RETRY) 00238 s = TAO_INVOKE_RESTART; 00239 else if (status == PortableInterceptor::SYSTEM_EXCEPTION 00240 || status == PortableInterceptor::USER_EXCEPTION) 00241 #endif /*TAO_HAS_INTERCEPTORS*/ 00242 ACE_RE_THROW; 00243 } 00244 # if defined (ACE_HAS_EXCEPTIONS) \ 00245 && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS) 00246 ACE_CATCHALL 00247 { 00248 #if TAO_HAS_INTERCEPTORS == 1 00249 const PortableInterceptor::ReplyStatus st = 00250 this->handle_all_exception (ACE_ENV_SINGLE_ARG_PARAMETER); 00251 ACE_TRY_CHECK; 00252 00253 if (st == PortableInterceptor::LOCATION_FORWARD || 00254 st == PortableInterceptor::TRANSPORT_RETRY) 00255 s = TAO_INVOKE_RESTART; 00256 else 00257 #endif /*TAO_HAS_INTERCEPTORS == 1*/ 00258 ACE_RE_THROW; 00259 } 00260 # endif /* ACE_HAS_EXCEPTIONS && 00261 ACE_HAS_BROKEN_UNEXPECTED_EXCEPTION*/ 00262 ACE_ENDTRY; 00263 ACE_CHECK_RETURN (TAO_INVOKE_FAILURE); 00264 00265 return s; 00266 } |
|
As the name suggests waits for a reply from the remote ORB. This method returns an exception when there is an error. Definition at line 269 of file Synch_Invocation.cpp. References ACE_CATCHANY, ACE_DEBUG, ACE_ENDTRY, ACE_ENV_ARG_PARAMETER, ACE_RE_THROW, ACE_THROW_RETURN, ACE_TRY, ACE_TRY_CHECK, ETIME, LM_DEBUG, TAO_debug_level, TAO::TAO_INVOKE_FAILURE, TAO::TAO_INVOKE_SUCCESS, and TAO_TIMEOUT_RECV_MINOR_CODE.
00274 { 00275 /* 00276 * Precondition: The call went to the remote 00277 * peer. <ACE_Thread::self> is waiting for the reply. 00278 * 00279 * Postcondition: Any error during a wait is marked by raising an 00280 * exception. Success alone is returned through the return value. 00281 */ 00282 00283 const int reply_error = 00284 this->resolver_.transport ()->wait_strategy ()->wait (max_wait_time, 00285 rd); 00286 if (TAO_debug_level > 0 && max_wait_time != 0) 00287 { 00288 const CORBA::ULong msecs = max_wait_time->msec (); 00289 00290 ACE_DEBUG ((LM_DEBUG, 00291 "TAO (%P|%t) - Synch_Twoway_Invocation::wait_for_reply, " 00292 "timeout after recv is <%u> status <%d>\n", 00293 msecs, 00294 reply_error)); 00295 } 00296 00297 // Check the reply error. 00298 if (reply_error == -1) 00299 { 00300 // Unbind the dispatcher, since its of no use at this point of 00301 // time 00302 if (TAO_debug_level > 3) 00303 { 00304 ACE_DEBUG ((LM_DEBUG, 00305 "TAO (%P|%t) - Synch_Twoway_Invocation::wait_for_reply, " 00306 "recovering after an error \n")); 00307 } 00308 00309 // You the smarty, don't try to moving the unbind_dispatcher 00310 // () call since it looks like it is repeated twice. That 00311 // could land you in trouble. If you don't believe this 00312 // warning go ahead and try. Try running tests to see what is 00313 // going on ;) 00314 if (errno == ETIME) 00315 { 00316 // If the unbind succeeds then thrown an exception to the 00317 // application, else just collect the reply and dispatch 00318 // that to the application. 00319 // 00320 // NOTE: A fragile synchronization is provided when using 00321 // the Muxed Transport strategy. We could infact be a 00322 // follower thread getting timedout in the LF whereas the 00323 // dispatching thread could be on the reply_dispatcher 00324 // that we created. This would lead bad crashes. To get 00325 // around that, the call to unbind_dispatcher () will wait 00326 // on the lock on the Muxed_Transport_Strategy if 00327 // dispatching has started. This is fragile. 00328 if (bd.unbind_dispatcher () == 0) 00329 { 00330 // Just a timeout with completed_maybe, don't close 00331 // the connection or anything 00332 ACE_THROW_RETURN (CORBA::TIMEOUT ( 00333 CORBA::SystemException::_tao_minor_code ( 00334 TAO_TIMEOUT_RECV_MINOR_CODE, 00335 errno), 00336 CORBA::COMPLETED_MAYBE), 00337 TAO_INVOKE_FAILURE); 00338 } 00339 } 00340 else 00341 { 00342 (void) bd.unbind_dispatcher (); 00343 this->resolver_.transport ()->close_connection (); 00344 00345 ACE_TRY 00346 { 00347 return 00348 this->orb_core ()->service_raise_comm_failure ( 00349 this->details_.request_service_context ().service_info (), 00350 this->resolver_.profile () 00351 ACE_ENV_ARG_PARAMETER); 00352 ACE_TRY_CHECK; 00353 00354 } 00355 ACE_CATCHANY 00356 { 00357 this->resolver_.stub ()->reset_profiles (); 00358 ACE_RE_THROW; 00359 } 00360 ACE_ENDTRY; 00361 } 00362 } 00363 00364 return TAO_INVOKE_SUCCESS; 00365 } |