Persistent_Context_Index.cpp

Go to the documentation of this file.
00001 // Persistent_Context_Index.cpp,v 1.35 2006/03/14 06:14:34 jtc Exp
00002 
00003 #include "orbsvcs/Naming/Persistent_Context_Index.h"
00004 #include "orbsvcs/Naming/Persistent_Naming_Context.h"
00005 
00006 #include "tao/debug.h"
00007 
00008 #include "ace/Auto_Ptr.h"
00009 #include "ace/OS_NS_unistd.h"
00010 
00011 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00012 
00013 int
00014 TAO_Persistent_Context_Index::unbind (const char *poa_id)
00015 {
00016   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, -1);
00017 
00018   TAO_Persistent_Index_ExtId name (poa_id);
00019   TAO_Persistent_Index_IntId entry;
00020   if (this->index_->unbind (name, entry, this->allocator_) != 0)
00021     return -1;
00022   else
00023     {
00024       // Free up the memory we allocated in bind().
00025       this->allocator_->free ((void *) (entry.counter_));
00026       return 0;
00027     }
00028 }
00029 
00030 int
00031 TAO_Persistent_Context_Index::bind (const char *poa_id,
00032                                     ACE_UINT32 *&counter,
00033                                     TAO_Persistent_Context_Index::CONTEXT *hash_map)
00034 {
00035   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, -1);
00036 
00037   // Allocate memory for items to be stored in the table.
00038   size_t poa_id_len = ACE_OS::strlen (poa_id) + 1;
00039   size_t counter_len = sizeof (ACE_UINT32);
00040   char *ptr = (char *) this->allocator_->malloc (poa_id_len + counter_len);
00041 
00042   if (ptr == 0)
00043     return -1;
00044   else
00045     {
00046       // Populate memory with data.
00047       counter = reinterpret_cast<ACE_UINT32 *> (ptr);
00048       *counter = 0;
00049       char * poa_id_ptr = ptr + counter_len;
00050       ACE_OS::strcpy (poa_id_ptr, poa_id);
00051 
00052       TAO_Persistent_Index_ExtId name (poa_id_ptr);
00053       TAO_Persistent_Index_IntId entry (counter, hash_map);
00054       int result = -1;
00055 
00056       // Do a normal bind.  This will fail if there's already an
00057       // entry with the same name.
00058       result = this->index_->bind (name, entry, this->allocator_);
00059 
00060       if (result == 1)
00061         {
00062           // Entry already existed so bind failed. Free our dynamically
00063           // allocated memory.
00064           this->allocator_->free ((void *) ptr);
00065           return result;
00066         }
00067 
00068       if (result == -1)
00069         // Free our dynamically allocated memory.
00070         this->allocator_->free ((void *) ptr);
00071       else
00072         // If bind() succeed, it will automatically sync
00073         // up the map manager entry.  However, we must sync up our
00074         // name/value memory.
00075         this->allocator_->sync (ptr, poa_id_len + counter_len);
00076 
00077       return result;
00078     }
00079 }
00080 
00081 TAO_Persistent_Context_Index::TAO_Persistent_Context_Index
00082   (CORBA::ORB_ptr orb,
00083    PortableServer::POA_ptr poa)
00084   : allocator_ (0),
00085     index_ (0),
00086     index_file_ (0),
00087     base_address_ (0),
00088     orb_ (CORBA::ORB::_duplicate (orb)),
00089     poa_ (PortableServer::POA::_duplicate (poa))
00090 {
00091 }
00092 
00093 TAO_Persistent_Context_Index::~TAO_Persistent_Context_Index (void)
00094 {
00095   delete allocator_;
00096   ACE_OS::free (reinterpret_cast<void *> (const_cast<ACE_TCHAR *> (index_file_)));
00097 }
00098 
00099 ACE_Allocator*
00100 TAO_Persistent_Context_Index::allocator (void)
00101 {
00102   return allocator_;
00103 }
00104 
00105 CosNaming::NamingContext_ptr
00106 TAO_Persistent_Context_Index::root_context (void)
00107 {
00108   return CosNaming::NamingContext::_duplicate (root_context_.in ());
00109 }
00110 
00111 CORBA::ORB_ptr
00112 TAO_Persistent_Context_Index::orb (void)
00113 {
00114   return orb_.in ();
00115 }
00116 
00117 int
00118 TAO_Persistent_Context_Index::open (const ACE_TCHAR *file_name,
00119                                     void *base_address)
00120 {
00121   this->base_address_ = base_address;
00122 
00123   index_file_ = ACE_OS::strdup (file_name);
00124   if (index_file_ == 0)
00125     return -1;
00126 
00127   return create_index ();
00128 }
00129 
00130 int
00131 TAO_Persistent_Context_Index::init (size_t context_size)
00132 {
00133   // Note: in case of an early exit from this (or helper) function due
00134   // to an error condition, we rely on POA to clean up all of the servants
00135   // already registered with it.
00136 
00137   // Return value of this function (necessary to keep compilers quiet).
00138   int status = 0;
00139 
00140   if (index_->current_size () == 0)
00141     // CASE 1:there are no Naming Contexts registered.  We need to create
00142     // one.
00143     {
00144       ACE_DECLARE_NEW_CORBA_ENV;
00145 
00146       this->root_context_ =
00147         TAO_Persistent_Naming_Context::make_new_context (poa_.in (),
00148                                                          TAO_ROOT_NAMING_CONTEXT,
00149                                                          context_size,
00150                                                          this
00151                                                          ACE_ENV_ARG_PARAMETER);
00152       ACE_CHECK_RETURN (-1);
00153     }
00154 
00155   else
00156     // CASE 2:Recreate all Naming Contexts.
00157     status = recreate_all ();
00158 
00159   return status;
00160 }
00161 
00162 int
00163 TAO_Persistent_Context_Index::recreate_all (void)
00164 {
00165   CONTEXT_INDEX::ITERATOR *index_iter = 0;
00166 
00167   ACE_NEW_RETURN (index_iter,
00168                   (CONTEXT_INDEX::ITERATOR) (*index_),
00169                   -1);
00170 
00171   ACE_Auto_Basic_Ptr<CONTEXT_INDEX::ITERATOR> it (index_iter);
00172 
00173   // Because of broken old g++!!!
00174   typedef ACE_Hash_Map_With_Allocator<TAO_Persistent_Index_ExtId,
00175     TAO_Persistent_Index_IntId>  IND_DEF;
00176 
00177   IND_DEF::ENTRY *entry = 0;
00178 
00179   if (TAO_debug_level > 0)
00180     ACE_DEBUG ((LM_DEBUG, "Starting to recreate Naming Contexts from the file... \n"));
00181 
00182   // For each entry in <index_>, create a Naming Context servant.
00183   do
00184     {
00185       index_iter->next (entry);
00186 
00187       // Put together a servant for the new Naming Context.
00188 
00189       TAO_Persistent_Naming_Context *context_impl = 0;
00190       ACE_NEW_RETURN (context_impl,
00191                       TAO_Persistent_Naming_Context (poa_.in (),
00192                                                      entry->ext_id_.poa_id_,
00193                                                      this,
00194                                                      entry->int_id_.hash_map_,
00195                                                      entry->int_id_.counter_),
00196                   -1);
00197 
00198 
00199       // Put <context_impl> into the auto pointer temporarily, in case next
00200       // allocation fails.
00201       ACE_Auto_Basic_Ptr<TAO_Persistent_Naming_Context> temp (context_impl);
00202 
00203       TAO_Naming_Context *context = 0;
00204       ACE_NEW_RETURN (context,
00205                       TAO_Naming_Context (context_impl),
00206                       -1);
00207 
00208       // Let <implementation> know about it's <interface>.
00209       context_impl->interface (context);
00210 
00211       // Release auto pointer and start using reference counting to
00212       // control our servant.
00213       temp.release ();
00214       PortableServer::ServantBase_var s = context;
00215 
00216       // Register with the POA.
00217       ACE_DECLARE_NEW_CORBA_ENV;
00218       PortableServer::ObjectId_var id =
00219         PortableServer::string_to_ObjectId (entry->ext_id_.poa_id_);
00220 
00221       this->poa_->activate_object_with_id (id.in (),
00222                                            context
00223                                            ACE_ENV_ARG_PARAMETER);
00224       ACE_CHECK_RETURN (-1);
00225 
00226       CosNaming::NamingContext_var result = context->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
00227       ACE_CHECK_RETURN (-1);
00228 
00229       // If this is the root Naming Context, take a note of it.
00230       if (context_impl->root ())
00231           this->root_context_= result._retn ();
00232 
00233     } while (index_iter->advance ());
00234 
00235   return 0;
00236 }
00237 
00238 int
00239 TAO_Persistent_Context_Index::create_index (void)
00240 {
00241   // Make sure that the file name is of the legal length.
00242   if (ACE_OS::strlen (index_file_) >= MAXNAMELEN + MAXPATHLEN)
00243     {
00244       errno = ENAMETOOLONG;
00245       return -1;
00246     }
00247 
00248 #if !defined (CHORUS)
00249   ACE_MMAP_Memory_Pool::OPTIONS options (base_address_);
00250 #else
00251   // Use base address == 0, don't use a fixed address.
00252   ACE_MMAP_Memory_Pool::OPTIONS options (0,
00253                                          0,
00254                                          0,
00255                                          ACE_CHORUS_LOCAL_NAME_SPACE_T_SIZE);
00256 #endif /* CHORUS */
00257 
00258   // Create the allocator with the appropriate options.  The name used
00259   // for  the lock is the same as one used for the file.
00260   ACE_NEW_RETURN (this->allocator_,
00261                   ALLOCATOR (this->index_file_,
00262                              this->index_file_,
00263                              &options),
00264                   -1);
00265 
00266 #if !defined (ACE_LACKS_ACCESS)
00267   // Now check if the backing store has been created successfully.
00268   if (ACE_OS::access (this->index_file_, F_OK) != 0)
00269     ACE_ERROR_RETURN ((LM_ERROR,
00270                        "create_index\n"),
00271                       -1);
00272 #endif /* ACE_LACKS_ACCESS */
00273 
00274   void *context_index = 0;
00275 
00276   // This is the easy case since if we find hash table in the
00277   // memory-mapped file we know it's already initialized.
00278   if (this->allocator_->find (TAO_NAMING_CONTEXT_INDEX, context_index) == 0)
00279     this->index_ = (CONTEXT_INDEX *) context_index;
00280 
00281   // Create a new <index_> (because we've just created a new
00282   // memory-mapped file).
00283   else
00284     {
00285       size_t index_size = sizeof (CONTEXT_INDEX);
00286       context_index = this->allocator_->malloc (index_size);
00287 
00288       if (context_index == 0
00289           || create_index_helper (context_index) == -1
00290           || this->allocator_->bind (TAO_NAMING_CONTEXT_INDEX,
00291                                      context_index) == -1)
00292         {
00293           // Attempt to clean up.
00294           ACE_ERROR ((LM_ERROR,
00295                       "create_index\n"));
00296           this->allocator_->remove ();
00297           return -1;
00298         }
00299     }
00300   return 0;
00301 }
00302 
00303 int
00304 TAO_Persistent_Context_Index::create_index_helper (void *buffer)
00305 {
00306   this->index_ = new (buffer) CONTEXT_INDEX (this->allocator_);
00307   return 0;
00308 }
00309 
00310 TAO_END_VERSIONED_NAMESPACE_DECL

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