#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 }
|
1.3.6