summaryrefslogtreecommitdiff
path: root/ACE/TAO/tao/PI_Server/ServerInterceptorAdapter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/TAO/tao/PI_Server/ServerInterceptorAdapter.cpp')
-rw-r--r--ACE/TAO/tao/PI_Server/ServerInterceptorAdapter.cpp553
1 files changed, 553 insertions, 0 deletions
diff --git a/ACE/TAO/tao/PI_Server/ServerInterceptorAdapter.cpp b/ACE/TAO/tao/PI_Server/ServerInterceptorAdapter.cpp
new file mode 100644
index 00000000000..3a3da8b5430
--- /dev/null
+++ b/ACE/TAO/tao/PI_Server/ServerInterceptorAdapter.cpp
@@ -0,0 +1,553 @@
+// $Id$
+
+#include "tao/PI_Server/ServerInterceptorAdapter.h"
+
+#if TAO_HAS_INTERCEPTORS == 1
+
+ACE_RCSID (PI_Server,
+ ServerInterceptorAdapter,
+ "$Id$")
+
+#include "tao/PI_Server/ServerRequestInfo.h"
+#include "tao/PI_Server/PICurrent_Guard.h"
+
+#include "tao/ServerRequestInterceptor_Adapter.h"
+#include "tao/TAO_Server_Request.h"
+#include "tao/ORB_Core.h"
+#include "tao/PI/PICurrent_Impl.h"
+#include "tao/PortableServer/Upcall_Command.h"
+#include "tao/PortableInterceptor.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO::ServerRequestInterceptor_Adapter_Impl::ServerRequestInterceptor_Adapter_Impl (void)
+{
+}
+
+#if TAO_HAS_EXTENDED_FT_INTERCEPTORS == 1
+void
+TAO::ServerRequestInterceptor_Adapter_Impl::tao_ft_interception_point (
+ TAO_ServerRequest &server_request,
+ TAO::Argument * const args[],
+ size_t nargs,
+ void * servant_upcall,
+ CORBA::TypeCode_ptr const * exceptions,
+ CORBA::ULong nexceptions,
+ CORBA::OctetSeq_out oc)
+{
+ // This method implements one of the "starting" server side
+ // interception point.
+
+ try
+ {
+ oc = 0;
+
+ bool is_remote_request = !server_request.collocated ();
+ TAO::ServerRequestInfo request_info (server_request,
+ args,
+ nargs,
+ servant_upcall,
+ exceptions,
+ nexceptions);
+
+ for (size_t i = 0 ; i < this->interceptor_list_.size(); ++i)
+ {
+ ServerRequestInterceptor_List::RegisteredInterceptor& registered =
+ this->interceptor_list_.registered_interceptor (i);
+
+ if (registered.details_.should_be_processed (is_remote_request))
+ {
+ registered.interceptor_->
+ tao_ft_interception_point (&request_info, oc);
+ }
+
+ if (oc != 0)
+ {
+ (void) this->send_other (server_request,
+ args,
+ nargs,
+ servant_upcall,
+ exceptions,
+ nexceptions);
+
+ return;
+ }
+
+ // The starting interception point completed successfully.
+ // Push the interceptor on to the flow stack.
+ ++server_request.interceptor_count ();
+ }
+ }
+ catch (const ::PortableInterceptor::ForwardRequest& exc)
+ {
+ server_request.forward_location (exc.forward.in ());
+ server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
+ server_request.reply_status (GIOP::LOCATION_FORWARD);
+ (void) this->send_other (server_request,
+ args,
+ nargs,
+ servant_upcall,
+ exceptions,
+ nexceptions);
+ }
+}
+
+void
+TAO::ServerRequestInterceptor_Adapter_Impl::receive_request_service_contexts (
+ TAO_ServerRequest &server_request,
+ TAO::Argument * const args[],
+ size_t nargs,
+ void * servant_upcall,
+ CORBA::TypeCode_ptr const * exceptions,
+ CORBA::ULong nexceptions)
+{
+ // This method implements one of the "intermediate" server side
+ // interception point.
+
+ if (this->interceptor_list_.size() != server_request.interceptor_count ())
+ {
+ // This method (i.e. the receive_request() interception point)
+ // should only be invoked if all of the interceptors registered
+ // with the ORB were pushed on to the flow stack by one of the
+ // starting endpoints (such as
+ // tao_ft_interception_point()). If the above condition
+ // evaluates to "true," then it is likely that a starting
+ // interception point was never invoked. This is of course, an
+ // internal error that must be corrected.
+ throw ::CORBA::INTERNAL ();
+ }
+
+ try
+ {
+ // Copy the request scope current (RSC) to the thread scope
+ // current (TSC) upon leaving this scope, i.e. just after the
+ // receive_request_service_contexts() completes. A "guard" is
+ // used to make the copy also occur if an exception is thrown.
+ TAO::PICurrent_Guard const pi_guard (server_request,
+ false /* Copy RSC to TSC */);
+
+ bool is_remote_request = !server_request.collocated ();
+ TAO::ServerRequestInfo request_info (server_request,
+ args,
+ nargs,
+ servant_upcall,
+ exceptions,
+ nexceptions);
+
+ for (size_t i = 0 ; i < server_request.interceptor_count (); ++i)
+ {
+ ServerRequestInterceptor_List::RegisteredInterceptor& registered =
+ this->interceptor_list_.registered_interceptor (i);
+
+ if (registered.details_.should_be_processed (is_remote_request))
+ {
+ registered.interceptor_->
+ receive_request_service_contexts (&request_info);
+ }
+ }
+ }
+ catch (const ::PortableInterceptor::ForwardRequest& exc)
+ {
+ server_request.forward_location (exc.forward.in ());
+ server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
+ server_request.reply_status (GIOP::LOCATION_FORWARD);
+ (void) this->send_other (server_request,
+ args,
+ nargs,
+ servant_upcall,
+ exceptions,
+ nexceptions);
+ }
+}
+
+#elif TAO_HAS_EXTENDED_FT_INTERCEPTORS == 0
+
+/// NOTE: Yes, we have two versions of this. This is easier than
+/// messing around things in the same function, which is harder to
+/// read and could make the code buggier.
+void
+TAO::ServerRequestInterceptor_Adapter_Impl::receive_request_service_contexts (
+ TAO_ServerRequest &server_request,
+ TAO::Argument * const args[],
+ size_t nargs,
+ void * servant_upcall,
+ CORBA::TypeCode_ptr const * exceptions,
+ CORBA::ULong nexceptions)
+{
+ // This method implements one of the "starting" server side
+ // interception point if extended interceptors are not in place.
+
+ try
+ {
+ // Copy the request scope current (RSC) to the thread scope
+ // current (TSC) upon leaving this scope, i.e. just after the
+ // receive_request_service_contexts() completes. A "guard" is
+ // used to make the copy also occur if an exception is thrown.
+ TAO::PICurrent_Guard const pi_guard (server_request,
+ false /* Copy RSC to TSC */);
+
+ bool is_remote_request = !server_request.collocated ();
+
+ TAO::ServerRequestInfo request_info (server_request,
+ args,
+ nargs,
+ servant_upcall,
+ exceptions,
+ nexceptions);
+
+ for (size_t i = 0 ; i < this->interceptor_list_.size(); ++i)
+ {
+ ServerRequestInterceptor_List::RegisteredInterceptor& registered =
+ this->interceptor_list_.registered_interceptor (i);
+
+ if (registered.details_.should_be_processed (is_remote_request))
+ {
+ registered.interceptor_->
+ receive_request_service_contexts (&request_info);
+ }
+
+ // The starting interception point completed successfully.
+ // Push the interceptor on to the flow stack.
+ ++server_request.interceptor_count ();
+ }
+ }
+ catch (const ::PortableInterceptor::ForwardRequest& exc)
+ {
+ server_request.forward_location (exc.forward.in ());
+ server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
+ server_request.reply_status (GIOP::LOCATION_FORWARD);
+ (void) this->send_other (server_request,
+ args,
+ nargs,
+ servant_upcall,
+ exceptions,
+ nexceptions);
+ }
+}
+
+#endif /*TAO_HAS_EXTENDED_FT_INTERCEPTORS*/
+
+void
+TAO::ServerRequestInterceptor_Adapter_Impl::receive_request (
+ TAO_ServerRequest &server_request,
+ TAO::Argument * const args[],
+ size_t nargs,
+ void * servant_upcall,
+ CORBA::TypeCode_ptr const * exceptions,
+ CORBA::ULong nexceptions
+ )
+{
+ // This method implements an "intermediate" server side interception
+ // point. Interceptors are invoked in the same order they were
+ // pushed on to the flow stack.
+
+ if (this->interceptor_list_.size() != server_request.interceptor_count ())
+ {
+ // This method (i.e. the receive_request() interception point)
+ // should only be invoked if all of the interceptors registered
+ // with the ORB were pushed on to the flow stack by one of the
+ // starting endpoints (such as
+ // receive_request_service_contexts()). If the above condition
+ // evaluates to "true," then it is likely that a starting
+ // interception point was never invoked. This is of course, an
+ // internal error that must be corrected.
+ throw ::CORBA::INTERNAL ();
+ }
+
+ TAO::ServerRequestInfo request_info (server_request,
+ args,
+ nargs,
+ servant_upcall,
+ exceptions,
+ nexceptions);
+
+ try
+ {
+ bool is_remote_request = !server_request.collocated ();
+
+ for (size_t i = 0; i < server_request.interceptor_count (); ++i)
+ {
+ ServerRequestInterceptor_List::RegisteredInterceptor& registered =
+ this->interceptor_list_.registered_interceptor (i);
+
+ if (registered.details_.should_be_processed (is_remote_request))
+ {
+ registered.interceptor_->receive_request (&request_info);
+ }
+
+ // Note that no interceptors are pushed on to or popped off
+ // of the flow stack in this interception point since it is
+ // an intermediate interception point.
+ }
+ }
+ catch (const ::PortableInterceptor::ForwardRequest& exc)
+ {
+ server_request.forward_location (exc.forward.in ());
+ server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
+ server_request.reply_status (GIOP::LOCATION_FORWARD);
+ this->send_other (server_request,
+ args,
+ nargs,
+ servant_upcall,
+ exceptions,
+ nexceptions);
+ }
+
+}
+
+void
+TAO::ServerRequestInterceptor_Adapter_Impl::send_reply (
+ TAO_ServerRequest &server_request,
+ TAO::Argument * const args[],
+ size_t nargs,
+ void * servant_upcall,
+ CORBA::TypeCode_ptr const * exceptions,
+ CORBA::ULong nexceptions)
+{
+ // This is an "ending" interception point so we only process the
+ // interceptors pushed on to the flow stack.
+
+ bool const is_remote_request = !server_request.collocated ();
+
+ // Notice that the interceptors are processed in the opposite order
+ // they were pushed onto the stack since this is an "ending"
+ // interception point.
+
+ TAO::ServerRequestInfo request_info (server_request,
+ args,
+ nargs,
+ servant_upcall,
+ exceptions,
+ nexceptions);
+
+ // Unwind the stack.
+ size_t const len = server_request.interceptor_count ();
+ for (size_t i = 0; i < len; ++i)
+ {
+ // Pop the interceptor off of the flow stack before it is
+ // invoked. This is necessary to prevent an interceptor already
+ // invoked in this "ending" interception point from being
+ // invoked in another "ending" interception point.
+ --server_request.interceptor_count ();
+
+ ServerRequestInterceptor_List::RegisteredInterceptor& registered =
+ this->interceptor_list_.registered_interceptor (
+ server_request.interceptor_count ());
+
+ if (registered.details_.should_be_processed (is_remote_request))
+ {
+ registered.interceptor_->send_reply (&request_info);
+ }
+ }
+
+ // The send_reply() interception point does not raise a
+ // PortableInterceptor::ForwardRequest exception so there is no need
+ // to attempt to catch it here.
+}
+
+void
+TAO::ServerRequestInterceptor_Adapter_Impl::send_exception (
+ TAO_ServerRequest &server_request,
+ TAO::Argument * const args[],
+ size_t nargs,
+ void * servant_upcall,
+ CORBA::TypeCode_ptr const * exceptions,
+ CORBA::ULong nexceptions)
+{
+ // This is an "ending" server side interception point so we only
+ // process the interceptors pushed on to the flow stack.
+
+ bool is_remote_request = !server_request.collocated ();
+
+ // Notice that the interceptors are processed in the opposite order
+ // they were pushed onto the stack since this is an "ending" server
+ // side interception point.
+
+ TAO::ServerRequestInfo request_info (server_request,
+ args,
+ nargs,
+ servant_upcall,
+ exceptions,
+ nexceptions);
+
+ try
+ {
+ // Unwind the flow stack.
+ size_t const len = server_request.interceptor_count ();
+ for (size_t i = 0; i < len; ++i)
+ {
+ // Pop the interceptor off of the flow stack before it is
+ // invoked. This is necessary to prevent an interceptor
+ // already invoked in this "ending" interception point from
+ // being invoked in another "ending" interception point.
+ --server_request.interceptor_count ();
+
+ ServerRequestInterceptor_List::RegisteredInterceptor& registered =
+ this->interceptor_list_.registered_interceptor (
+ server_request.interceptor_count ());
+
+ if (registered.details_.should_be_processed (is_remote_request))
+ {
+ registered.interceptor_->send_exception (&request_info);
+ }
+ }
+ }
+ catch (const ::PortableInterceptor::ForwardRequest& exc)
+ {
+ server_request.forward_location (exc.forward.in ());
+ server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
+ server_request.reply_status (GIOP::LOCATION_FORWARD);
+ this->send_other (server_request,
+ args,
+ nargs,
+ servant_upcall,
+ exceptions,
+ nexceptions);
+ }
+ catch ( ::CORBA::Exception& ex)
+ {
+ // The send_exception() interception point in the remaining
+ // interceptors must be called so call this method (not the
+ // interceptor's corresponding method) recursively. The call is
+ // made recursively since the caught exception must survive
+ // until the remaining interceptors have been called.
+ //
+ // Note that the recursion will stop once the flow stack size
+ // drops to zero, i.e., once each interceptor has been invoked.
+ // This prevents infinite recursion from occuring.
+
+ server_request.caught_exception (&ex);
+
+ this->send_exception (server_request,
+ args,
+ nargs,
+ servant_upcall,
+ exceptions,
+ nexceptions);
+
+ PortableInterceptor::ReplyStatus status =
+ server_request.pi_reply_status ();
+
+ // Only re-throw the exception if it hasn't been transformed by
+ // the send_exception() interception point (e.g. to a
+ // LOCATION_FORWARD).
+ if (status == PortableInterceptor::SYSTEM_EXCEPTION
+ || status == PortableInterceptor::USER_EXCEPTION)
+ throw;
+ }
+}
+
+void
+TAO::ServerRequestInterceptor_Adapter_Impl::send_other (
+ TAO_ServerRequest &server_request,
+ TAO::Argument * const args[],
+ size_t nargs,
+ void * servant_upcall,
+ CORBA::TypeCode_ptr const * exceptions,
+ CORBA::ULong nexceptions)
+{
+ // This is an "ending" server side interception point so we only
+ // process the interceptors pushed on to the flow stack.
+
+ bool is_remote_request = !server_request.collocated ();
+
+ TAO::ServerRequestInfo request_info (server_request,
+ args,
+ nargs,
+ servant_upcall,
+ exceptions,
+ nexceptions);
+
+ // Notice that the interceptors are processed in the opposite order
+ // they were pushed onto the stack since this is an "ending" server
+ // side interception point.
+
+ try
+ {
+ // Unwind the flow stack.
+ size_t const len = server_request.interceptor_count ();
+ for (size_t i = 0; i < len; ++i)
+ {
+ // Pop the interceptor off of the flow stack before it is
+ // invoked. This is necessary to prevent an interceptor
+ // already invoked in this "ending" interception point from
+ // being invoked in another "ending" interception point.
+ --server_request.interceptor_count ();
+
+ ServerRequestInterceptor_List::RegisteredInterceptor& registered =
+ this->interceptor_list_.registered_interceptor (
+ server_request.interceptor_count ());
+
+ if (registered.details_.should_be_processed (is_remote_request))
+ {
+ registered.interceptor_->send_other (&request_info);
+ }
+ }
+ }
+ catch (const ::PortableInterceptor::ForwardRequest& exc)
+ {
+ server_request.forward_location (exc.forward.in ());
+ server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
+ server_request.reply_status (GIOP::LOCATION_FORWARD);
+ this->send_other (server_request,
+ args,
+ nargs,
+ servant_upcall,
+ exceptions,
+ nexceptions);
+ }
+}
+
+void
+TAO::ServerRequestInterceptor_Adapter_Impl::add_interceptor (
+ PortableInterceptor::ServerRequestInterceptor_ptr interceptor)
+{
+ this->interceptor_list_.add_interceptor (interceptor);
+}
+
+void
+TAO::ServerRequestInterceptor_Adapter_Impl::add_interceptor (
+ PortableInterceptor::ServerRequestInterceptor_ptr interceptor,
+ const CORBA::PolicyList& policies)
+{
+ this->interceptor_list_.add_interceptor (interceptor, policies);
+}
+
+void
+TAO::ServerRequestInterceptor_Adapter_Impl::destroy_interceptors (void)
+{
+ this->interceptor_list_.destroy_interceptors ();
+}
+
+TAO::PICurrent_Impl *
+TAO::ServerRequestInterceptor_Adapter_Impl::allocate_pi_current (void)
+{
+ TAO::PICurrent_Impl *pi = 0;
+ ACE_NEW_RETURN (pi,
+ TAO::PICurrent_Impl,
+ pi);
+ return pi;
+}
+
+void
+TAO::ServerRequestInterceptor_Adapter_Impl::deallocate_pi_current (
+ TAO::PICurrent_Impl *picurrent)
+{
+ delete picurrent;
+}
+
+void
+TAO::ServerRequestInterceptor_Adapter_Impl::execute_command (
+ TAO_ServerRequest & server_request,
+ TAO::Upcall_Command & command)
+{
+ TAO::PICurrent_Guard const pi_guard (server_request,
+ true /* Copy TSC to RSC */);
+
+ // The actual upcall.
+ command.execute ();
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_INTERCEPTORS == 1 */