00001 #include "orbsvcs/Naming/Persistent_Naming_Context.h"
00002 #include "orbsvcs/Naming/Persistent_Context_Index.h"
00003 #include "orbsvcs/Naming/Bindings_Iterator_T.h"
00004 #include "ace/OS_NS_stdio.h"
00005
00006 #include "ace/Auto_Ptr.h"
00007
00008 ACE_RCSID (Naming,
00009 Persistent_Naming_Context,
00010 "$Id: Persistent_Naming_Context.cpp 79963 2007-11-09 11:30:22Z johnnyw $")
00011
00012 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00013
00014 int
00015 TAO_Persistent_Bindings_Map::unbind (const char *id,
00016 const char *kind)
00017 {
00018 TAO_Persistent_ExtId name (id, kind);
00019 TAO_Persistent_IntId entry;
00020 if (this->map_->unbind (name, entry, this->allocator_) != 0)
00021 return -1;
00022 else
00023 {
00024
00025
00026
00027
00028 this->allocator_->free ((void *) (entry.ref_));
00029 return 0;
00030 }
00031 }
00032
00033 int
00034 TAO_Persistent_Bindings_Map::bind (const char *id,
00035 const char *kind,
00036 CORBA::Object_ptr obj,
00037 CosNaming::BindingType type)
00038 {
00039 return this->shared_bind (id, kind, obj, type, 0);
00040 }
00041
00042 int
00043 TAO_Persistent_Bindings_Map::rebind (const char *id,
00044 const char *kind,
00045 CORBA::Object_ptr obj,
00046 CosNaming::BindingType type)
00047 {
00048 return this->shared_bind (id, kind, obj, type, 1);
00049 }
00050
00051 int
00052 TAO_Persistent_Bindings_Map::find (const char *id,
00053 const char *kind,
00054 CORBA::Object_ptr & obj,
00055 CosNaming::BindingType &type)
00056 {
00057 TAO_Persistent_ExtId name (id, kind);
00058 TAO_Persistent_IntId entry;
00059
00060 if (this->map_->find (name, entry, this->allocator_) != 0)
00061 return -1;
00062 else
00063 {
00064 obj = orb_->string_to_object (entry.ref_);
00065 type = entry.type_;
00066
00067 return 0;
00068 }
00069 }
00070
00071 TAO_Persistent_Bindings_Map::TAO_Persistent_Bindings_Map (CORBA::ORB_ptr orb)
00072 : allocator_ (0),
00073 map_ (0),
00074 orb_ (CORBA::ORB::_duplicate (orb))
00075 {
00076 }
00077
00078 TAO_Persistent_Bindings_Map::~TAO_Persistent_Bindings_Map (void)
00079 {
00080 }
00081
00082 void
00083 TAO_Persistent_Bindings_Map::destroy (void)
00084 {
00085 this->map_->ACE_Hash_Map_With_Allocator<TAO_Persistent_ExtId, TAO_Persistent_IntId>::~ACE_Hash_Map_With_Allocator ();
00086 this->allocator_->free (map_);
00087 }
00088
00089 TAO_Persistent_Bindings_Map::HASH_MAP *
00090 TAO_Persistent_Bindings_Map::map (void)
00091 {
00092 return this->map_;
00093 }
00094
00095 size_t
00096 TAO_Persistent_Bindings_Map::total_size (void)
00097 {
00098 return this->map_->total_size ();
00099 }
00100
00101 size_t
00102 TAO_Persistent_Bindings_Map::current_size (void)
00103 {
00104 return map_->current_size ();
00105 }
00106
00107 int
00108 TAO_Persistent_Bindings_Map::open (size_t hash_table_size, ACE_Allocator *alloc)
00109 {
00110 allocator_ = alloc;
00111
00112
00113 void *hash_map = 0;
00114 size_t map_size = sizeof (HASH_MAP);
00115 hash_map = this->allocator_->malloc (map_size);
00116
00117
00118 if (hash_map == 0)
00119 return -1;
00120
00121
00122 if (open_helper (hash_table_size, hash_map) == -1)
00123 this->allocator_->free (hash_map);
00124
00125 return 0;
00126 }
00127
00128 int
00129 TAO_Persistent_Bindings_Map::open_helper (size_t hash_table_size,
00130 void *buffer)
00131 {
00132 this->map_ = new (buffer) HASH_MAP (hash_table_size, this->allocator_);
00133 return 0;
00134 }
00135
00136 void
00137 TAO_Persistent_Bindings_Map::set (HASH_MAP *map, ACE_Allocator *alloc)
00138 {
00139 allocator_ = alloc;
00140 map_ = map;
00141 }
00142
00143 int
00144 TAO_Persistent_Bindings_Map::shared_bind (const char * id,
00145 const char * kind,
00146 CORBA::Object_ptr obj,
00147 CosNaming::BindingType type,
00148 int rebind)
00149 {
00150
00151 CORBA::String_var ref = orb_->object_to_string (obj);
00152
00153
00154
00155 size_t id_len = ACE_OS::strlen (id) + 1;
00156 size_t kind_len = ACE_OS::strlen (kind) + 1;
00157 size_t ref_len = ACE_OS::strlen (ref.in ()) + 1;
00158 size_t total_len = id_len + kind_len + ref_len;
00159 char *ptr = (char *) this->allocator_->malloc (total_len);
00160
00161
00162 if (ptr == 0)
00163 return -1;
00164
00165
00166
00167 else
00168 {
00169
00170
00171 char * ref_ptr = ptr;
00172 char * id_ptr = ptr + ref_len;
00173 char * kind_ptr = ptr + ref_len + id_len;
00174 ACE_OS::strcpy (ref_ptr, ref.in ());
00175 ACE_OS::strcpy (id_ptr, id);
00176 ACE_OS::strcpy (kind_ptr, kind);
00177
00178 TAO_Persistent_ExtId new_name (id_ptr, kind_ptr);
00179 TAO_Persistent_IntId new_entry (ref_ptr, type);
00180 int result = -1;
00181
00182 if (rebind == 0)
00183 {
00184
00185
00186 result = this->map_->bind (new_name, new_entry, this->allocator_);
00187
00188 if (result == 1)
00189 {
00190
00191
00192 this->allocator_->free ((void *) ptr);
00193 return result;
00194 }
00195 }
00196 else
00197
00198 {
00199 TAO_Persistent_ExtId old_name;
00200 TAO_Persistent_IntId old_entry;
00201
00202
00203 if (this->map_->find (new_name,
00204 old_entry,
00205 this->allocator_) == 0
00206 && type != old_entry.type_)
00207 result = -2;
00208
00209
00210 else
00211 result = this->map_->rebind (new_name, new_entry,
00212 old_name, old_entry,
00213 this->allocator_);
00214 if (result == 1)
00215 {
00216
00217
00218
00219
00220 this->allocator_->free ((void *) old_entry.ref_);
00221 }
00222 }
00223
00224
00225
00226 if (result < 0)
00227 this->allocator_->free ((void *) ptr);
00228
00229 else
00230
00231
00232
00233 this->allocator_->sync (ptr, total_len);
00234
00235 return result;
00236 }
00237 }
00238
00239 TAO_Persistent_Naming_Context::TAO_Persistent_Naming_Context (PortableServer::POA_ptr poa,
00240 const char *poa_id,
00241 TAO_Persistent_Context_Index *context_index)
00242
00243 : TAO_Hash_Naming_Context (poa,
00244 poa_id),
00245 counter_ (0),
00246 persistent_context_ (0),
00247 index_ (context_index)
00248 {
00249 ACE_NEW (this->persistent_context_,
00250 TAO_Persistent_Bindings_Map (context_index->orb ()));
00251
00252
00253 context_ = persistent_context_;
00254 }
00255
00256 TAO_Persistent_Naming_Context::TAO_Persistent_Naming_Context (PortableServer::POA_ptr poa,
00257 const char *poa_id,
00258 TAO_Persistent_Context_Index *context_index,
00259 HASH_MAP *map,
00260 ACE_UINT32 *counter)
00261 : TAO_Hash_Naming_Context (poa,
00262 poa_id),
00263 counter_ (counter),
00264 persistent_context_ (0),
00265 index_ (context_index)
00266 {
00267 ACE_NEW (this->persistent_context_,
00268 TAO_Persistent_Bindings_Map (context_index->orb ()));
00269
00270
00271 context_ = persistent_context_;
00272
00273 persistent_context_->set (map, index_->allocator ());
00274 }
00275
00276 int
00277 TAO_Persistent_Naming_Context::init (size_t hash_table_size)
00278 {
00279 return persistent_context_->open (hash_table_size, index_->allocator ());
00280 }
00281
00282 TAO_Persistent_Naming_Context::~TAO_Persistent_Naming_Context (void)
00283 {
00284
00285
00286 if (this->destroyed_ > 1)
00287 {
00288
00289 index_->unbind (poa_id_.c_str ());
00290
00291 persistent_context_->destroy ();
00292 }
00293 else if (this->destroyed_ == 1)
00294
00295 persistent_context_->destroy ();
00296 }
00297
00298 void
00299 TAO_Persistent_Naming_Context::set_cleanup_level (int level)
00300 {
00301 this->destroyed_ = level;
00302 }
00303
00304 CosNaming::NamingContext_ptr
00305 TAO_Persistent_Naming_Context::make_new_context (PortableServer::POA_ptr poa,
00306 const char *poa_id,
00307 size_t context_size,
00308 TAO_Persistent_Context_Index * ind)
00309 {
00310
00311 CosNaming::NamingContext_var result;
00312
00313
00314
00315 TAO_Persistent_Naming_Context *context_impl = 0;
00316 ACE_NEW_THROW_EX (context_impl,
00317 TAO_Persistent_Naming_Context (poa,
00318 poa_id,
00319 ind),
00320 CORBA::NO_MEMORY ());
00321
00322
00323
00324 ACE_Auto_Basic_Ptr<TAO_Persistent_Naming_Context> temp (context_impl);
00325
00326 if (context_impl->init (context_size) == -1)
00327 throw CORBA::NO_MEMORY ();
00328
00329
00330 context_impl->set_cleanup_level (1);
00331
00332
00333 if (ind->bind (context_impl->poa_id_.c_str (),
00334 context_impl->counter_,
00335 context_impl->persistent_context_->map ()) == -1)
00336 throw CORBA::INTERNAL ();
00337
00338
00339 context_impl->set_cleanup_level (2);
00340
00341 TAO_Naming_Context *context = 0;
00342 ACE_NEW_THROW_EX (context,
00343 TAO_Naming_Context (context_impl),
00344 CORBA::NO_MEMORY ());
00345
00346
00347 context_impl->interface (context);
00348
00349
00350
00351 temp.release ();
00352 PortableServer::ServantBase_var s = context;
00353
00354
00355 PortableServer::ObjectId_var id =
00356 PortableServer::string_to_ObjectId (poa_id);
00357
00358 poa->activate_object_with_id (id.in (),
00359 context);
00360
00361 result = context->_this ();
00362
00363
00364 context_impl->set_cleanup_level (0);
00365
00366 return result._retn ();
00367 }
00368
00369 CosNaming::NamingContext_ptr
00370 TAO_Persistent_Naming_Context::new_context (void)
00371 {
00372 ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX,
00373 ace_mon,
00374 this->lock_,
00375 CORBA::INTERNAL ());
00376
00377
00378
00379 if (this->destroyed_)
00380 throw CORBA::OBJECT_NOT_EXIST ();
00381
00382
00383 char poa_id[BUFSIZ];
00384 ACE_OS::sprintf (poa_id,
00385 "%s_%d",
00386 this->poa_id_.c_str (),
00387 (*this->counter_)++);
00388
00389 CosNaming::NamingContext_var result =
00390 make_new_context (this->poa_.in (),
00391 poa_id,
00392 this->persistent_context_->total_size (),
00393 this->index_);
00394
00395 return result._retn ();
00396 }
00397
00398 void
00399 TAO_Persistent_Naming_Context::list (CORBA::ULong how_many,
00400 CosNaming::BindingList_out &bl,
00401 CosNaming::BindingIterator_out &bi)
00402 {
00403
00404
00405 bi = CosNaming::BindingIterator::_nil ();
00406 ACE_NEW_THROW_EX (bl,
00407 CosNaming::BindingList (0),
00408 CORBA::NO_MEMORY ());
00409
00410
00411 ACE_GUARD_THROW_EX (TAO_SYNCH_RECURSIVE_MUTEX,
00412 ace_mon,
00413 this->lock_,
00414 CORBA::INTERNAL ());
00415
00416
00417
00418 if (this->destroyed_)
00419 throw CORBA::OBJECT_NOT_EXIST ();
00420
00421
00422 HASH_MAP::ITERATOR *hash_iter = 0;
00423 ACE_NEW_THROW_EX (hash_iter,
00424 HASH_MAP::ITERATOR
00425 (*persistent_context_->map ()),
00426 CORBA::NO_MEMORY ());
00427
00428
00429
00430 ACE_Auto_Basic_Ptr<HASH_MAP::ITERATOR> temp (hash_iter);
00431
00432
00433
00434 typedef ACE_Hash_Map_With_Allocator<TAO_Persistent_ExtId, TAO_Persistent_IntId>::ITERATOR ITER_DEF;
00435 typedef ACE_Hash_Map_With_Allocator<TAO_Persistent_ExtId, TAO_Persistent_IntId>::ENTRY ENTRY_DEF;
00436
00437
00438 typedef TAO_Bindings_Iterator<ITER_DEF, ENTRY_DEF> ITER_SERVANT;
00439
00440
00441 ITER_SERVANT *bind_iter = 0;
00442
00443
00444 CORBA::ULong n;
00445
00446
00447 if (this->context_->current_size () > how_many)
00448 n = how_many;
00449 else
00450 n = static_cast<CORBA::ULong> (this->context_->current_size ());
00451
00452
00453 bl->length (n);
00454
00455 ENTRY_DEF *hash_entry = 0;
00456
00457 for (CORBA::ULong i = 0; i < n; i++)
00458 {
00459 hash_iter->next (hash_entry);
00460 hash_iter->advance ();
00461
00462 if (ITER_SERVANT::populate_binding (hash_entry, bl[i]) == 0)
00463 throw CORBA::NO_MEMORY();
00464 }
00465
00466
00467
00468
00469
00470 if (this->context_->current_size () <= how_many)
00471 return;
00472 else
00473 {
00474
00475 ACE_NEW_THROW_EX (bind_iter,
00476 ITER_SERVANT (this, hash_iter, this->poa_.in (), this->lock_),
00477 CORBA::NO_MEMORY ());
00478
00479
00480
00481 temp.release ();
00482 PortableServer::ServantBase_var iter = bind_iter;
00483
00484
00485
00486 interface_->_add_ref ();
00487
00488
00489 char poa_id[BUFSIZ];
00490 ACE_OS::sprintf (poa_id,
00491 "%s_%d",
00492 this->poa_id_.c_str (),
00493 (*this->counter_)++);
00494 PortableServer::ObjectId_var id =
00495 PortableServer::string_to_ObjectId (poa_id);
00496
00497 this->poa_->activate_object_with_id (id.in (),
00498 bind_iter);
00499
00500 bi = bind_iter->_this ();
00501 }
00502 }
00503
00504 TAO_END_VERSIONED_NAMESPACE_DECL