Transient_Naming_Context.cpp

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

Generated on Thu Nov 9 13:57:03 2006 for TAO_CosNaming by doxygen 1.3.6