Transient_Naming_Context.cpp

Go to the documentation of this file.
00001 //=============================================================================
00002 /**
00003  *  @file   Transient_Naming_Context.cpp
00004  *
00005  *  $Id: Transient_Naming_Context.cpp 81142 2008-03-28 14:36:30Z elliott_c $
00006  *
00007  *  @author Marina Spivak <marina@cs.wustl.edu> and Sergio Flores-Gaitan <sergio@cs.wustl.edu>
00008  */
00009 //=============================================================================
00010 
00011 #include "ace/Auto_Ptr.h"
00012 #include "orbsvcs/Naming/Transient_Naming_Context.h"
00013 #include "orbsvcs/Naming/Bindings_Iterator_T.h"
00014 #include "ace/OS_NS_stdio.h"
00015 
00016 ACE_RCSID(Naming, Transient_Naming_Context, "$Id: Transient_Naming_Context.cpp 81142 2008-03-28 14:36:30Z elliott_c $")
00017 
00018 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 int
00021 TAO_Transient_Bindings_Map::unbind (const char *id, const char *kind)
00022 {
00023   TAO_ExtId name (id, kind);
00024   return this->map_.unbind (name);
00025 }
00026 
00027 int
00028 TAO_Transient_Bindings_Map::bind (const char *id,
00029                                   const char *kind,
00030                                   CORBA::Object_ptr obj,
00031                                   CosNaming::BindingType type)
00032 {
00033   return this->shared_bind (id, kind, obj, type, 0);
00034 }
00035 
00036 int
00037 TAO_Transient_Bindings_Map::rebind (const char *id,
00038                                     const char *kind,
00039                                     CORBA::Object_ptr obj,
00040                                     CosNaming::BindingType type)
00041 {
00042   return this->shared_bind (id, kind, obj, type, 1);
00043 }
00044 
00045 int
00046 TAO_Transient_Bindings_Map::find (const char *id,
00047                                   const char *kind,
00048                                   CORBA::Object_ptr & obj,
00049                                   CosNaming::BindingType &type)
00050 {
00051   TAO_ExtId name (id, kind);
00052   TAO_IntId entry;
00053 
00054   if (this->map_.find (name,
00055                        entry) != 0)
00056     return -1;
00057   else
00058     {
00059       obj = CORBA::Object::_duplicate (entry.ref_);
00060       type = entry.type_;
00061       return 0;
00062     }
00063 }
00064 
00065 TAO_Transient_Bindings_Map::TAO_Transient_Bindings_Map (size_t hash_table_size)
00066   : map_ (hash_table_size)
00067 {
00068 }
00069 
00070 TAO_Transient_Bindings_Map::~TAO_Transient_Bindings_Map (void)
00071 {
00072 }
00073 
00074 TAO_Transient_Bindings_Map::HASH_MAP &
00075 TAO_Transient_Bindings_Map::map (void)
00076 {
00077   return map_;
00078 }
00079 
00080 size_t
00081 TAO_Transient_Bindings_Map::current_size (void)
00082 {
00083   return map_.current_size ();
00084 }
00085 
00086 size_t
00087 TAO_Transient_Bindings_Map::total_size (void)
00088 {
00089   return map_.total_size ();
00090 }
00091 
00092 int
00093 TAO_Transient_Bindings_Map::shared_bind (const char * id,
00094                                          const char * kind,
00095                                          CORBA::Object_ptr obj,
00096                                          CosNaming::BindingType type,
00097                                          int rebind)
00098 {
00099   TAO_ExtId new_name (id, kind);
00100   TAO_IntId new_entry (obj, type);
00101   TAO_IntId old_entry;
00102 
00103   if (rebind == 0)
00104     // Do a normal bind.
00105     return this->map_.bind (new_name, new_entry);
00106 
00107   else
00108     // Rebind.
00109     {
00110       // Check that types of old and new entries match.
00111       if (this->map_.find (new_name,
00112                            old_entry) == 0
00113           && type != old_entry.type_)
00114         return -2;
00115 
00116       else
00117         return this->map_.rebind (new_name, new_entry);
00118     }
00119 }
00120 
00121 TAO_Transient_Naming_Context::TAO_Transient_Naming_Context (PortableServer::POA_ptr poa,
00122                                                             const char *poa_id,
00123                                                             size_t hash_table_size)
00124   : TAO_Hash_Naming_Context (poa,
00125                              poa_id),
00126     counter_ (0),
00127     transient_context_ (0)
00128 {
00129   ACE_NEW (this->transient_context_,
00130            TAO_Transient_Bindings_Map (hash_table_size));
00131 
00132   context_ = transient_context_;
00133 }
00134 
00135 TAO_Transient_Naming_Context::~TAO_Transient_Naming_Context (void)
00136 {
00137 }
00138 
00139 CosNaming::NamingContext_ptr
00140 TAO_Transient_Naming_Context::make_new_context (PortableServer::POA_ptr poa,
00141                                                 const char *poa_id,
00142                                                 size_t context_size)
00143 {
00144   // Store the stub we will return here.
00145   CosNaming::NamingContext_var result;
00146 
00147   // Put together a servant for the new Naming Context.
00148 
00149   TAO_Transient_Naming_Context *context_impl = 0;
00150   ACE_NEW_THROW_EX (context_impl,
00151                     TAO_Transient_Naming_Context (poa,
00152                                                   poa_id,
00153                                                   context_size),
00154                     CORBA::NO_MEMORY ());
00155 
00156   // Put <context_impl> into the auto pointer temporarily, in case next
00157   // allocation fails.
00158   ACE_Auto_Basic_Ptr<TAO_Transient_Naming_Context> temp (context_impl);
00159 
00160   TAO_Naming_Context *context = 0;
00161   ACE_NEW_THROW_EX (context,
00162                     TAO_Naming_Context (context_impl),
00163                     CORBA::NO_MEMORY ());
00164 
00165   // Let <implementation> know about it's <interface>.
00166   context_impl->interface (context);
00167 
00168   // Release auto pointer, and start using reference counting to
00169   // control our servant.
00170   temp.release ();
00171   PortableServer::ServantBase_var s = context;
00172 
00173   // Register the new context with the POA.
00174 #if defined (CORBA_E_MICRO)
00175   PortableServer::ObjectId_var id = poa->activate_object (context);
00176 #else
00177   PortableServer::ObjectId_var id =
00178     PortableServer::string_to_ObjectId (poa_id);
00179 
00180   poa->activate_object_with_id (id.in (), context);
00181 #endif /* CORBA_E_MICRO */
00182 
00183   result = context->_this ();
00184 
00185   return result._retn ();
00186 }
00187 
00188 CosNaming::NamingContext_ptr
00189 TAO_Transient_Naming_Context::new_context (void)
00190 {
00191   ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX,
00192                       ace_mon,
00193                       this->lock_,
00194                       CORBA::INTERNAL ());
00195 
00196   // Check to make sure this object didn't have <destroy> method
00197   // invoked on it.
00198   if (this->destroyed_)
00199     throw CORBA::OBJECT_NOT_EXIST ();
00200 
00201   // Generate a POA id for the new context.
00202   char poa_id[BUFSIZ];
00203   ACE_OS::sprintf (poa_id,
00204                    "%s_%d",
00205                    this->poa_id_.c_str (),
00206                    this->counter_++);
00207 
00208   // Create a new context.
00209   CosNaming::NamingContext_var result =
00210     make_new_context (this->poa_.in (),
00211                       poa_id,
00212                       this->transient_context_->total_size ());
00213 
00214   return result._retn ();
00215 }
00216 
00217 void
00218 TAO_Transient_Naming_Context::list (CORBA::ULong how_many,
00219                                     CosNaming::BindingList_out &bl,
00220                                     CosNaming::BindingIterator_out &bi)
00221 {
00222   // Allocate nil out parameters in case we won't be able to complete
00223   // the operation.
00224   bi = CosNaming::BindingIterator::_nil ();
00225   ACE_NEW_THROW_EX (bl,
00226                     CosNaming::BindingList (0),
00227                     CORBA::NO_MEMORY ());
00228 
00229   // Obtain a lock before we proceed with the operation.
00230   ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX,
00231                       ace_mon,
00232                       this->lock_,
00233                       CORBA::INTERNAL ());
00234 
00235   // Check to make sure this object didn't have <destroy> method
00236   // invoked on it.
00237   if (this->destroyed_)
00238     throw CORBA::OBJECT_NOT_EXIST ();
00239 
00240   // Dynamically allocate iterator for traversing the underlying hash map.
00241   HASH_MAP::ITERATOR *hash_iter = 0;
00242   ACE_NEW_THROW_EX (hash_iter,
00243                     HASH_MAP::ITERATOR (transient_context_->map ()),
00244                     CORBA::NO_MEMORY ());
00245 
00246   // Store <hash_iter temporarily in auto pointer, in case we'll have
00247   // some failures and throw an exception.
00248   ACE_Auto_Basic_Ptr<HASH_MAP::ITERATOR> temp (hash_iter);
00249 
00250   // Silliness below is required because of broken old g++!!!  E.g.,
00251   // without it, we could have just said HASH_MAP::ITERATOR everywhere we use ITER_DEF.
00252   typedef ACE_Hash_Map_Manager<TAO_ExtId, TAO_IntId, ACE_Null_Mutex>::ITERATOR ITER_DEF;
00253   typedef ACE_Hash_Map_Manager<TAO_ExtId, TAO_IntId, ACE_Null_Mutex>::ENTRY ENTRY_DEF;
00254 
00255   // Typedef to the type of BindingIterator servant for ease of use.
00256   typedef TAO_Bindings_Iterator<ITER_DEF, ENTRY_DEF>
00257     ITER_SERVANT;
00258 
00259   // A pointer to BindingIterator servant.
00260   ITER_SERVANT *bind_iter = 0;
00261 
00262   // Number of bindings that will go into the BindingList <bl>.
00263   CORBA::ULong n;
00264 
00265   // Calculate number of bindings that will go into <bl>.
00266   if (this->context_->current_size () > how_many)
00267     n = how_many;
00268   else
00269     n = static_cast<CORBA::ULong> (this->context_->current_size ());
00270 
00271   // Use the hash map iterator to populate <bl> with bindings.
00272   bl->length (n);
00273 
00274   ENTRY_DEF *hash_entry = 0;
00275 
00276   for (CORBA::ULong i = 0; i < n; i++)
00277     {
00278       hash_iter->next (hash_entry);
00279       hash_iter->advance ();
00280 
00281       if (ITER_SERVANT::populate_binding (hash_entry, bl[i]) == 0)
00282           throw CORBA::NO_MEMORY();
00283     }
00284 
00285   // Now we are done with the BindingsList, and we can follow up on
00286   // the BindingIterator business.
00287 
00288   // If we do not need to pass back BindingIterator.
00289   if (this->context_->current_size () <= how_many)
00290     return;
00291   else
00292     {
00293       // Create a BindingIterator for return.
00294       ACE_NEW_THROW_EX (bind_iter,
00295                         ITER_SERVANT (this, hash_iter, this->poa_.in (), this->lock_),
00296                         CORBA::NO_MEMORY ());
00297 
00298       // Release <hash_iter> from auto pointer, and start using
00299       // reference counting to control our servant.
00300       temp.release ();
00301       PortableServer::ServantBase_var iter = bind_iter;
00302 
00303       // Increment reference count on this Naming Context, so it doesn't get
00304       // deleted before the BindingIterator servant gets deleted.
00305       interface_->_add_ref ();
00306 
00307       // Register with the POA.
00308       char poa_id[BUFSIZ];
00309       ACE_OS::sprintf (poa_id,
00310                        "%s_%d",
00311                        this->poa_id_.c_str (),
00312                        this->counter_++);
00313 #if defined (CORBA_E_MICRO)
00314       PortableServer::ObjectId_var id =
00315         this->poa_->activate_object (bind_iter);
00316 #else
00317       PortableServer::ObjectId_var id =
00318         PortableServer::string_to_ObjectId (poa_id);
00319 
00320       this->poa_->activate_object_with_id (id.in (),
00321                                            bind_iter);
00322 #endif /* CORBA_E_MICRO */
00323 
00324       bi = bind_iter->_this ();
00325     }
00326 }
00327 
00328 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:49:05 2010 for TAO_CosNaming by  doxygen 1.4.7