Interceptor_List_T.cpp

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

Generated on Tue Feb 2 17:42:01 2010 for TAO_PI by  doxygen 1.4.7