Interceptor_List_T.cpp

Go to the documentation of this file.
00001 // Interceptor_List_T.cpp,v 1.8 2006/03/10 07:19:12 jtc Exp
00002 
00003 #include "tao/PI/ORBInitInfoC.h"
00004 #include "tao/PI/InterceptorC.h"
00005 #include "tao/SystemException.h"
00006 #include "tao/ORB_Constants.h"
00007 #include "tao/debug.h"
00008 
00009 #include "ace/os_include/os_stddef.h"
00010 #include "ace/OS_NS_string.h"
00011 #include "ace/Log_Msg.h"
00012 
00013 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00014 
00015 namespace TAO
00016 {
00017   template <typename InterceptorType, typename DetailsType>
00018   Interceptor_List<InterceptorType,DetailsType>::Interceptor_List (void)
00019   {
00020   }
00021 
00022   template <typename InterceptorType, typename DetailsType>
00023   typename Interceptor_List<InterceptorType,DetailsType>::RegisteredInterceptor&
00024   Interceptor_List<InterceptorType,DetailsType>::registered_interceptor (
00025     size_t index)
00026   {
00027     return this->interceptors_[index];
00028   }
00029 
00030   template <typename InterceptorType, typename DetailsType>
00031   typename Interceptor_List<InterceptorType,DetailsType>::InterceptorType_ptr_type
00032   Interceptor_List<InterceptorType,DetailsType>::interceptor (size_t index)
00033   {
00034     return this->interceptors_[index].interceptor_.in ();
00035   }
00036 
00037   template <typename InterceptorType, typename DetailsType>
00038   size_t
00039   Interceptor_List<InterceptorType,DetailsType>::size (void)
00040   {
00041     return this->interceptors_.size ();
00042   }
00043 
00044   template <typename InterceptorType, typename DetailsType>
00045   void
00046   Interceptor_List<InterceptorType,DetailsType>::add_interceptor (
00047     InterceptorType_ptr_type interceptor
00048     ACE_ENV_ARG_DECL)
00049   {
00050     if (!CORBA::is_nil (interceptor))
00051       {
00052         const size_t old_len = this->interceptors_.size ();
00053 
00054         // Don't bother checking the name for duplicates if no
00055         // interceptors have been registered.  This saves an
00056         // allocation.
00057         if (old_len > 0)
00058           {
00059             /// If the Interceptor is not anonymous, make sure an
00060             /// Interceptor with the same isn't already registered.
00061             CORBA::String_var name =
00062               interceptor->name (ACE_ENV_SINGLE_ARG_PARAMETER);
00063             ACE_CHECK;
00064 
00065             if (ACE_OS::strlen (name.in ()) != 0)
00066               {
00067                 // @@ This simple search algorithm isn't the greatest
00068                 //    thing in the world, but since we only register
00069                 //    interceptors when bootstrapping an ORB, there will
00070                 //    be no runtime penalty.
00071                 //
00072                 //    Another source of inefficiency is that
00073                 //    Interceptors duplicate their name each time the
00074                 //    name() accessor is called!  This can slow down
00075                 //    bootstrap time noticeably when registering a huge
00076                 //    number of interceptors.  We could cache the names
00077                 //    somewhere, but since this is only a bootstrapping
00078                 //    issue there's no rush to implement such a scheme.
00079 
00080                 // Prevent interceptors with the same name from being
00081                 // registered.  Anonymous interceptors are okay.
00082                 for (size_t i = 0; i < old_len; ++i)
00083                   {
00084                     CORBA::String_var existing_name =
00085                       this->interceptor (i)->name ();
00086 
00087                     if (ACE_OS::strcmp (existing_name.in (),
00088                                         name.in ()) == 0)
00089                       {
00090                         ACE_THROW (PortableInterceptor::ORBInitInfo::DuplicateName ());
00091                       }
00092                   }
00093               }
00094           }
00095 
00096         /// Increase the length of the Interceptor sequence by one.
00097         const size_t new_len = old_len + 1;
00098         this->interceptors_.size (new_len);
00099 
00100         // Add the interceptor
00101         this->interceptors_[old_len].interceptor_ =
00102           InterceptorType::_duplicate (interceptor);
00103       }
00104     else
00105       {
00106         ACE_THROW (
00107             CORBA::INV_OBJREF (
00108                 CORBA::SystemException::_tao_minor_code (
00109                     0,
00110                     EINVAL
00111                   ),
00112                 CORBA::COMPLETED_NO
00113               )
00114             );
00115       }
00116   }
00117 
00118   template <typename InterceptorType, typename DetailsType>
00119   void
00120   Interceptor_List<InterceptorType,DetailsType>::add_interceptor (
00121     InterceptorType_ptr_type interceptor,
00122     const CORBA::PolicyList& policies
00123     ACE_ENV_ARG_DECL)
00124   {
00125     if (!CORBA::is_nil (interceptor))
00126       {
00127         const size_t old_len = this->interceptors_.size ();
00128 
00129         // Don't bother checking the name for duplicates if no
00130         // interceptors have been registered.  This saves an
00131         // allocation.
00132         if (old_len > 0)
00133           {
00134             /// If the Interceptor is not anonymous, make sure an
00135             /// Interceptor with the same isn't already registered.
00136             CORBA::String_var name =
00137               interceptor->name (ACE_ENV_SINGLE_ARG_PARAMETER);
00138             ACE_CHECK;
00139 
00140             if (ACE_OS::strlen (name.in ()) != 0)
00141               {
00142                 // @@ This simple search algorithm isn't the greatest
00143                 //    thing in the world, but since we only register
00144                 //    interceptors when bootstrapping an ORB, there will
00145                 //    be no runtime penalty.
00146                 //
00147                 //    Another source of inefficiency is that
00148                 //    Interceptors duplicate their name each time the
00149                 //    name() accessor is called!  This can slow down
00150                 //    bootstrap time noticeably when registering a huge
00151                 //    number of interceptors.  We could cache the names
00152                 //    somewhere, but since this is only a bootstrapping
00153                 //    issue there's no rush to implement such a scheme.
00154 
00155                 // Prevent interceptors with the same name from being
00156                 // registered.  Anonymous interceptors are okay.
00157                 for (size_t i = 0; i < old_len; ++i)
00158                   {
00159                     CORBA::String_var existing_name =
00160                       this->interceptor (i)->name ();
00161 
00162                     if (ACE_OS::strcmp (existing_name.in (),
00163                                         name.in ()) == 0)
00164                       {
00165                         ACE_THROW (PortableInterceptor::ORBInitInfo::DuplicateName ());
00166                       }
00167                   }
00168               }
00169           }
00170 
00171         // Create a DetailsType object, and attempt to apply the policies.
00172         DetailsType details;
00173         details.apply_policies(policies ACE_ENV_ARG_PARAMETER);
00174         ACE_CHECK;
00175 
00176         /// Increase the length of the Interceptor sequence by one.
00177         const size_t new_len = old_len + 1;
00178         this->interceptors_.size (new_len);
00179 
00180         // Add the interceptor
00181         this->interceptors_[old_len].interceptor_ =
00182           InterceptorType::_duplicate (interceptor);
00183 
00184         // Set the details
00185         this->interceptors_[old_len].details_ = details;
00186       }
00187     else
00188       {
00189         ACE_THROW (
00190             CORBA::INV_OBJREF (
00191                 CORBA::SystemException::_tao_minor_code (
00192                     0,
00193                     EINVAL
00194                   ),
00195                 CORBA::COMPLETED_NO
00196               )
00197             );
00198       }
00199   }
00200 
00201   template <typename InterceptorType, typename DetailsType>
00202   void
00203   Interceptor_List<InterceptorType,DetailsType>::destroy_interceptors (
00204     ACE_ENV_SINGLE_ARG_DECL)
00205   {
00206     const size_t len = this->interceptors_.size ();
00207     size_t ilen = len;
00208 
00209     ACE_TRY
00210       {
00211         for (size_t k = 0; k < len; ++k)
00212           {
00213             // Destroy the interceptors in reverse order in case the
00214             // array list is only partially destroyed and another
00215             // invocation occurs afterwards.
00216             --ilen;
00217 
00218             this->interceptor (k)->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00219             ACE_TRY_CHECK;
00220 
00221             // Since Interceptor::destroy() can throw an exception,
00222             // decrease the size of the interceptor array incrementally
00223             // since some interceptors may not have been destroyed yet.
00224             // Note that this size reduction is fast since no memory is
00225             // actually deallocated.
00226             this->interceptors_.size (ilen);
00227           }
00228       }
00229     ACE_CATCHALL
00230       {
00231         // Exceptions should not be propagated beyond this call.
00232         if (TAO_debug_level > 3)
00233           {
00234             ACE_DEBUG ((LM_DEBUG,
00235                         ACE_TEXT ("TAO (%P|%t) - Exception in ")
00236                         ACE_TEXT ("Interceptor_List")
00237                         ACE_TEXT ("::destroy_interceptors () \n")));
00238           }
00239       }
00240     ACE_ENDTRY;
00241     ACE_CHECK;
00242   }
00243 }
00244 
00245 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 12:51:39 2006 for TAO_PI by doxygen 1.3.6