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