diff options
Diffstat (limited to 'ACE/TAO/tao/Collocated_Invocation.cpp')
-rw-r--r-- | ACE/TAO/tao/Collocated_Invocation.cpp | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/ACE/TAO/tao/Collocated_Invocation.cpp b/ACE/TAO/tao/Collocated_Invocation.cpp new file mode 100644 index 00000000000..bd696bbbfa8 --- /dev/null +++ b/ACE/TAO/tao/Collocated_Invocation.cpp @@ -0,0 +1,196 @@ +#include "tao/Collocated_Invocation.h" +#include "tao/Collocation_Proxy_Broker.h" +#include "tao/ORB_Core.h" +#include "tao/Request_Dispatcher.h" +#include "tao/TAO_Server_Request.h" +#include "tao/Stub.h" +#include "tao/operation_details.h" +#include "tao/PortableInterceptor.h" +#include "tao/SystemException.h" + +#if TAO_HAS_INTERCEPTORS == 1 +# include "tao/PortableInterceptorC.h" +#endif /*TAO_HAS_INTERCEPTORS */ + +ACE_RCSID (tao, + Collocated_Invocation, + "$Id$") + + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +namespace TAO +{ + Collocated_Invocation::Collocated_Invocation (CORBA::Object_ptr t, + CORBA::Object_ptr et, + TAO_Stub *stub, + TAO_Operation_Details &detail, + bool response_expected) + : Invocation_Base (t, + et, + stub, + detail, + response_expected, + false /* request_is_remote */ ) + { + } + + Invocation_Status + Collocated_Invocation::invoke (Collocation_Proxy_Broker *cpb, + Collocation_Strategy strat) + { + Invocation_Status s = TAO_INVOKE_FAILURE; + + /// Start the interception point +#if TAO_HAS_INTERCEPTORS == 1 + s = this->send_request_interception (); + + if (s != TAO_INVOKE_SUCCESS) + return s; +#endif /*TAO_HAS_INTERCEPTORS */ + + try + { + if (strat == TAO_CS_THRU_POA_STRATEGY) + { + // Perform invocations on the servant through the servant's ORB. + CORBA::ORB_var servant_orb = + this->effective_target ()->_stubobj ()->servant_orb_ptr (); + TAO_ORB_Core * const orb_core = servant_orb->orb_core (); + + TAO_ServerRequest request (orb_core, + this->details_, + this->effective_target ()); + + TAO_Request_Dispatcher * const dispatcher = + orb_core->request_dispatcher (); + + // Retain ownership of the servant's ORB_Core in case + // another thread attempts to destroy it (e.g. via + // CORBA::ORB::destroy()) before this thread complete the + // invocation. + orb_core->_incr_refcnt (); + TAO_ORB_Core_Auto_Ptr my_orb_core (orb_core); + + dispatcher->dispatch (orb_core, + request, + this->forwarded_to_.out ()); + + if (request.is_forwarded ()) + { + this->reply_status_ = GIOP::LOCATION_FORWARD; + } + } + else + { + bool is_forwarded = false; + + cpb->dispatch (this->effective_target (), + this->forwarded_to_.out (), + is_forwarded, + this->details_.args (), + this->details_.args_num (), + this->details_.opname (), + this->details_.opname_len (), + strat); + + if (is_forwarded) + { + this->reply_status_ = GIOP::LOCATION_FORWARD; + } + } + + // Invocation completed succesfully + s = TAO_INVOKE_SUCCESS; + +#if TAO_HAS_INTERCEPTORS == 1 + if (this->reply_status_ == GIOP::LOCATION_FORWARD || + this->response_expected_ == false) + { + if (this->reply_status_ == GIOP::LOCATION_FORWARD) + this->invoke_status (TAO_INVOKE_RESTART); + + s = this->receive_other_interception (); + } + // NOTE: Any other condition that needs handling? + else if (this->response_expected ()) + { + this->invoke_status (TAO_INVOKE_SUCCESS); + + s = this->receive_reply_interception (); + } + if (s != TAO_INVOKE_SUCCESS) + return s; +#endif /*TAO_HAS_INTERCEPTORS */ + } + catch ( ::CORBA::UserException& ex) + { + // Ignore CORBA exceptions for oneways + if (this->response_expected_ == false) + return TAO_INVOKE_SUCCESS; + +#if TAO_HAS_INTERCEPTORS == 1 + PortableInterceptor::ReplyStatus const status = + this->handle_any_exception (&ex); + + if (status == PortableInterceptor::LOCATION_FORWARD || + status == PortableInterceptor::TRANSPORT_RETRY) + s = TAO_INVOKE_RESTART; + else +#endif /* TAO_HAS_INTERCEPTORS */ + { + // Check whether the user exception thrown matches the signature + // list, if not, then throw an Unknown exception + if (!this->details_.has_exception (ex)) + { + throw ::CORBA::UNKNOWN (CORBA::OMGVMCID | 1, + CORBA::COMPLETED_MAYBE); + } + else + { + throw; + } + } + } + catch ( ::CORBA::SystemException& TAO_INTERCEPTOR (ex)) + { + // Ignore CORBA exceptions for oneways + if (this->response_expected_ == false) + return TAO_INVOKE_SUCCESS; + +#if TAO_HAS_INTERCEPTORS == 1 + PortableInterceptor::ReplyStatus const status = + this->handle_any_exception (&ex); + + if (status == PortableInterceptor::LOCATION_FORWARD || + status == PortableInterceptor::TRANSPORT_RETRY) + s = TAO_INVOKE_RESTART; + else +#endif /* TAO_HAS_INTERCEPTORS */ + throw; + } +#if TAO_HAS_INTERCEPTORS == 1 + catch (...) + { + // Notify interceptors of non-CORBA exception, and propagate + // that exception to the caller. + PortableInterceptor::ReplyStatus const st = + this->handle_all_exception (); + + if (st == PortableInterceptor::LOCATION_FORWARD || + st == PortableInterceptor::TRANSPORT_RETRY) + s = TAO_INVOKE_RESTART; + else + throw; + } +#endif /* TAO_HAS_INTERCEPTORS == 1 */ + + if (this->reply_status_ == GIOP::LOCATION_FORWARD) + s = TAO_INVOKE_RESTART; + + return s; + } + +} + +TAO_END_VERSIONED_NAMESPACE_DECL |