Interceptor_List_T.cpp

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

Generated on Sun Jan 27 13:29:59 2008 for TAO_PI by doxygen 1.3.6