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 77031 2007-02-12 15:20:17Z johnnyw $
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 77031 2007-02-12 15:20:17Z johnnyw $")
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   PortableServer::ObjectId_var id =
00175     PortableServer::string_to_ObjectId (poa_id);
00176 
00177   poa->activate_object_with_id (id.in (),
00178                                 context);
00179 
00180   result = context->_this ();
00181 
00182   return result._retn ();
00183 }
00184 
00185 CosNaming::NamingContext_ptr
00186 TAO_Transient_Naming_Context::new_context (void)
00187 {
00188   ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX,
00189                       ace_mon,
00190                       this->lock_,
00191                       CORBA::INTERNAL ());
00192 
00193   // Check to make sure this object didn't have <destroy> method
00194   // invoked on it.
00195   if (this->destroyed_)
00196     throw CORBA::OBJECT_NOT_EXIST ();
00197 
00198   // Generate a POA id for the new context.
00199   char poa_id[BUFSIZ];
00200   ACE_OS::sprintf (poa_id,
00201                    "%s_%d",
00202                    this->poa_id_.c_str (),
00203                    this->counter_++);
00204 
00205   // Create a new context.
00206   CosNaming::NamingContext_var result =
00207     make_new_context (this->poa_.in (),
00208                       poa_id,
00209                       this->transient_context_->total_size ());
00210 
00211   return result._retn ();
00212 }
00213 
00214 void
00215 TAO_Transient_Naming_Context::list (CORBA::ULong how_many,
00216                                     CosNaming::BindingList_out &bl,
00217                                     CosNaming::BindingIterator_out &bi)
00218 {
00219   // Allocate nil out parameters in case we won't be able to complete
00220   // the operation.
00221   bi = CosNaming::BindingIterator::_nil ();
00222   ACE_NEW_THROW_EX (bl,
00223                     CosNaming::BindingList (0),
00224                     CORBA::NO_MEMORY ());
00225 
00226   // Obtain a lock before we proceed with the operation.
00227   ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX,
00228                       ace_mon,
00229                       this->lock_,
00230                       CORBA::INTERNAL ());
00231 
00232   // Check to make sure this object didn't have <destroy> method
00233   // invoked on it.
00234   if (this->destroyed_)
00235     throw CORBA::OBJECT_NOT_EXIST ();
00236 
00237   // Dynamically allocate iterator for traversing the underlying hash map.
00238   HASH_MAP::ITERATOR *hash_iter = 0;
00239   ACE_NEW_THROW_EX (hash_iter,
00240                     HASH_MAP::ITERATOR (transient_context_->map ()),
00241                     CORBA::NO_MEMORY ());
00242 
00243   // Store <hash_iter temporarily in auto pointer, in case we'll have
00244   // some failures and throw an exception.
00245   ACE_Auto_Basic_Ptr<HASH_MAP::ITERATOR> temp (hash_iter);
00246 
00247   // Silliness below is required because of broken old g++!!!  E.g.,
00248   // without it, we could have just said HASH_MAP::ITERATOR everywhere we use ITER_DEF.
00249   typedef ACE_Hash_Map_Manager<TAO_ExtId, TAO_IntId, ACE_Null_Mutex>::ITERATOR ITER_DEF;
00250   typedef ACE_Hash_Map_Manager<TAO_ExtId, TAO_IntId, ACE_Null_Mutex>::ENTRY ENTRY_DEF;
00251 
00252   // Typedef to the type of BindingIterator servant for ease of use.
00253   typedef TAO_Bindings_Iterator<ITER_DEF, ENTRY_DEF>
00254     ITER_SERVANT;
00255 
00256   // A pointer to BindingIterator servant.
00257   ITER_SERVANT *bind_iter = 0;
00258 
00259   // Number of bindings that will go into the BindingList <bl>.
00260   CORBA::ULong n;
00261 
00262   // Calculate number of bindings that will go into <bl>.
00263   if (this->context_->current_size () > how_many)
00264     n = how_many;
00265   else
00266     n = static_cast<CORBA::ULong> (this->context_->current_size ());
00267 
00268   // Use the hash map iterator to populate <bl> with bindings.
00269   bl->length (n);
00270 
00271   ENTRY_DEF *hash_entry = 0;
00272 
00273   for (CORBA::ULong i = 0; i < n; i++)
00274     {
00275       hash_iter->next (hash_entry);
00276       hash_iter->advance ();
00277 
00278       if (ITER_SERVANT::populate_binding (hash_entry, bl[i]) == 0)
00279           throw CORBA::NO_MEMORY();
00280     }
00281 
00282   // Now we are done with the BindingsList, and we can follow up on
00283   // the BindingIterator business.
00284 
00285   // If we do not need to pass back BindingIterator.
00286   if (this->context_->current_size () <= how_many)
00287     return;
00288   else
00289     {
00290       // Create a BindingIterator for return.
00291       ACE_NEW_THROW_EX (bind_iter,
00292                         ITER_SERVANT (this, hash_iter, this->poa_.in (), this->lock_),
00293                         CORBA::NO_MEMORY ());
00294 
00295       // Release <hash_iter> from auto pointer, and start using
00296       // reference counting to control our servant.
00297       temp.release ();
00298       PortableServer::ServantBase_var iter = bind_iter;
00299 
00300       // Increment reference count on this Naming Context, so it doesn't get
00301       // deleted before the BindingIterator servant gets deleted.
00302       interface_->_add_ref ();
00303 
00304       // Register with the POA.
00305       char poa_id[BUFSIZ];
00306       ACE_OS::sprintf (poa_id,
00307                        "%s_%d",
00308                        this->poa_id_.c_str (),
00309                        this->counter_++);
00310       PortableServer::ObjectId_var id =
00311         PortableServer::string_to_ObjectId (poa_id);
00312 
00313       this->poa_->activate_object_with_id (id.in (),
00314                                            bind_iter);
00315 
00316       bi = bind_iter->_this ();
00317     }
00318 }
00319 
00320 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 16:15:32 2008 for TAO_CosNaming by doxygen 1.3.6