summaryrefslogtreecommitdiff
path: root/TAO/tao/PI/Interceptor_List_T.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/PI/Interceptor_List_T.cpp')
-rw-r--r--TAO/tao/PI/Interceptor_List_T.cpp245
1 files changed, 245 insertions, 0 deletions
diff --git a/TAO/tao/PI/Interceptor_List_T.cpp b/TAO/tao/PI/Interceptor_List_T.cpp
new file mode 100644
index 00000000000..657f69213ad
--- /dev/null
+++ b/TAO/tao/PI/Interceptor_List_T.cpp
@@ -0,0 +1,245 @@
+// $Id$
+
+#include "tao/PI/ORBInitInfoC.h"
+#include "tao/PI/InterceptorC.h"
+#include "tao/SystemException.h"
+#include "tao/ORB_Constants.h"
+#include "tao/debug.h"
+
+#include "ace/os_include/os_stddef.h"
+#include "ace/OS_NS_string.h"
+#include "ace/Log_Msg.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+ template <typename InterceptorType, typename DetailsType>
+ Interceptor_List<InterceptorType,DetailsType>::Interceptor_List (void)
+ {
+ }
+
+ template <typename InterceptorType, typename DetailsType>
+ typename Interceptor_List<InterceptorType,DetailsType>::RegisteredInterceptor&
+ Interceptor_List<InterceptorType,DetailsType>::registered_interceptor (
+ size_t index)
+ {
+ return this->interceptors_[index];
+ }
+
+ template <typename InterceptorType, typename DetailsType>
+ typename Interceptor_List<InterceptorType,DetailsType>::InterceptorType_ptr_type
+ Interceptor_List<InterceptorType,DetailsType>::interceptor (size_t index)
+ {
+ return this->interceptors_[index].interceptor_.in ();
+ }
+
+ template <typename InterceptorType, typename DetailsType>
+ size_t
+ Interceptor_List<InterceptorType,DetailsType>::size (void)
+ {
+ return this->interceptors_.size ();
+ }
+
+ template <typename InterceptorType, typename DetailsType>
+ void
+ Interceptor_List<InterceptorType,DetailsType>::add_interceptor (
+ InterceptorType_ptr_type interceptor
+ ACE_ENV_ARG_DECL)
+ {
+ if (!CORBA::is_nil (interceptor))
+ {
+ const size_t old_len = this->interceptors_.size ();
+
+ // Don't bother checking the name for duplicates if no
+ // interceptors have been registered. This saves an
+ // allocation.
+ if (old_len > 0)
+ {
+ /// If the Interceptor is not anonymous, make sure an
+ /// Interceptor with the same isn't already registered.
+ CORBA::String_var name =
+ interceptor->name (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (ACE_OS::strlen (name.in ()) != 0)
+ {
+ // @@ This simple search algorithm isn't the greatest
+ // thing in the world, but since we only register
+ // interceptors when bootstrapping an ORB, there will
+ // be no runtime penalty.
+ //
+ // Another source of inefficiency is that
+ // Interceptors duplicate their name each time the
+ // name() accessor is called! This can slow down
+ // bootstrap time noticeably when registering a huge
+ // number of interceptors. We could cache the names
+ // somewhere, but since this is only a bootstrapping
+ // issue there's no rush to implement such a scheme.
+
+ // Prevent interceptors with the same name from being
+ // registered. Anonymous interceptors are okay.
+ for (size_t i = 0; i < old_len; ++i)
+ {
+ CORBA::String_var existing_name =
+ this->interceptor (i)->name ();
+
+ if (ACE_OS::strcmp (existing_name.in (),
+ name.in ()) == 0)
+ {
+ ACE_THROW (PortableInterceptor::ORBInitInfo::DuplicateName ());
+ }
+ }
+ }
+ }
+
+ /// Increase the length of the Interceptor sequence by one.
+ const size_t new_len = old_len + 1;
+ this->interceptors_.size (new_len);
+
+ // Add the interceptor
+ this->interceptors_[old_len].interceptor_ =
+ InterceptorType::_duplicate (interceptor);
+ }
+ else
+ {
+ ACE_THROW (
+ CORBA::INV_OBJREF (
+ CORBA::SystemException::_tao_minor_code (
+ 0,
+ EINVAL
+ ),
+ CORBA::COMPLETED_NO
+ )
+ );
+ }
+ }
+
+ template <typename InterceptorType, typename DetailsType>
+ void
+ Interceptor_List<InterceptorType,DetailsType>::add_interceptor (
+ InterceptorType_ptr_type interceptor,
+ const CORBA::PolicyList& policies
+ ACE_ENV_ARG_DECL)
+ {
+ if (!CORBA::is_nil (interceptor))
+ {
+ const size_t old_len = this->interceptors_.size ();
+
+ // Don't bother checking the name for duplicates if no
+ // interceptors have been registered. This saves an
+ // allocation.
+ if (old_len > 0)
+ {
+ /// If the Interceptor is not anonymous, make sure an
+ /// Interceptor with the same isn't already registered.
+ CORBA::String_var name =
+ interceptor->name (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (ACE_OS::strlen (name.in ()) != 0)
+ {
+ // @@ This simple search algorithm isn't the greatest
+ // thing in the world, but since we only register
+ // interceptors when bootstrapping an ORB, there will
+ // be no runtime penalty.
+ //
+ // Another source of inefficiency is that
+ // Interceptors duplicate their name each time the
+ // name() accessor is called! This can slow down
+ // bootstrap time noticeably when registering a huge
+ // number of interceptors. We could cache the names
+ // somewhere, but since this is only a bootstrapping
+ // issue there's no rush to implement such a scheme.
+
+ // Prevent interceptors with the same name from being
+ // registered. Anonymous interceptors are okay.
+ for (size_t i = 0; i < old_len; ++i)
+ {
+ CORBA::String_var existing_name =
+ this->interceptor (i)->name ();
+
+ if (ACE_OS::strcmp (existing_name.in (),
+ name.in ()) == 0)
+ {
+ ACE_THROW (PortableInterceptor::ORBInitInfo::DuplicateName ());
+ }
+ }
+ }
+ }
+
+ // Create a DetailsType object, and attempt to apply the policies.
+ DetailsType details;
+ details.apply_policies(policies ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ /// Increase the length of the Interceptor sequence by one.
+ const size_t new_len = old_len + 1;
+ this->interceptors_.size (new_len);
+
+ // Add the interceptor
+ this->interceptors_[old_len].interceptor_ =
+ InterceptorType::_duplicate (interceptor);
+
+ // Set the details
+ this->interceptors_[old_len].details_ = details;
+ }
+ else
+ {
+ ACE_THROW (
+ CORBA::INV_OBJREF (
+ CORBA::SystemException::_tao_minor_code (
+ 0,
+ EINVAL
+ ),
+ CORBA::COMPLETED_NO
+ )
+ );
+ }
+ }
+
+ template <typename InterceptorType, typename DetailsType>
+ void
+ Interceptor_List<InterceptorType,DetailsType>::destroy_interceptors (
+ ACE_ENV_SINGLE_ARG_DECL)
+ {
+ const size_t len = this->interceptors_.size ();
+ size_t ilen = len;
+
+ ACE_TRY
+ {
+ for (size_t k = 0; k < len; ++k)
+ {
+ // Destroy the interceptors in reverse order in case the
+ // array list is only partially destroyed and another
+ // invocation occurs afterwards.
+ --ilen;
+
+ this->interceptor (k)->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Since Interceptor::destroy() can throw an exception,
+ // decrease the size of the interceptor array incrementally
+ // since some interceptors may not have been destroyed yet.
+ // Note that this size reduction is fast since no memory is
+ // actually deallocated.
+ this->interceptors_.size (ilen);
+ }
+ }
+ ACE_CATCHALL
+ {
+ // Exceptions should not be propagated beyond this call.
+ if (TAO_debug_level > 3)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Exception in ")
+ ACE_TEXT ("Interceptor_List")
+ ACE_TEXT ("::destroy_interceptors () \n")));
+ }
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+ }
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL