PG_ObjectGroupManager.cpp

Go to the documentation of this file.
00001 #include "orbsvcs/PortableGroup/PG_ObjectGroupManager.h"
00002 #include "orbsvcs/PortableGroup/PG_GenericFactory.h"
00003 #include "orbsvcs/PortableGroup/PG_conf.h"
00004 #include "orbsvcs/PortableGroup/PG_Operators.h"
00005 
00006 #include "tao/debug.h"
00007 #include "tao/ORB_Constants.h"
00008 
00009 #include "ace/Auto_Ptr.h"
00010 #include "ace/Reverse_Lock_T.h"
00011 
00012 ACE_RCSID (PortableGroup,
00013            PG_ObjectGroupManager,
00014            "$Id: PG_ObjectGroupManager.cpp 77001 2007-02-12 07:54:49Z johnnyw $")
00015 
00016 
00017 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00018 
00019 TAO_PG_ObjectGroupManager::TAO_PG_ObjectGroupManager (void)
00020   : poa_ (),
00021     object_group_map_ (TAO_PG_MAX_OBJECT_GROUPS),
00022     location_map_ (TAO_PG_MAX_LOCATIONS),
00023     generic_factory_ (0),
00024     lock_ ()
00025 {
00026 }
00027 
00028 TAO_PG_ObjectGroupManager::~TAO_PG_ObjectGroupManager (void)
00029 {
00030   for (TAO_PG_Location_Map::iterator i = this->location_map_.begin ();
00031        i != this->location_map_.end ();
00032        ++i)
00033     {
00034       // Destroy the group array
00035       delete (*i).int_id_;
00036     }
00037   (void) this->location_map_.close ();
00038 
00039   for (TAO_PG_ObjectGroup_Map::iterator j = this->object_group_map_.begin ();
00040        j != this->object_group_map_.end ();
00041        ++j)
00042     {
00043       // Destroy the object group entry
00044       delete (*j).int_id_;
00045     }
00046   (void) this->object_group_map_.close ();
00047 }
00048 
00049 PortableGroup::ObjectGroup_ptr
00050 TAO_PG_ObjectGroupManager::create_member (
00051     PortableGroup::ObjectGroup_ptr /* object_group */,
00052     const PortableGroup::Location & /* the_location */,
00053     const char * /* type_id */,
00054     const PortableGroup::Criteria & /* the_criteria */)
00055 {
00056   throw CORBA::NO_IMPLEMENT ();
00057 }
00058 
00059 PortableGroup::ObjectGroup_ptr
00060 TAO_PG_ObjectGroupManager::add_member (
00061     PortableGroup::ObjectGroup_ptr object_group,
00062     const PortableGroup::Location & the_location,
00063     CORBA::Object_ptr member)
00064 {
00065   if (CORBA::is_nil (member))
00066     throw CORBA::BAD_PARAM ();
00067 
00068   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00069                     guard,
00070                     this->lock_,
00071                     PortableGroup::ObjectGroup::_nil ());
00072 
00073   // Verify that the member's RepositoryId matches the object group's
00074   // type ID.
00075   const CORBA::Boolean check_type_id = 1;
00076 
00077   return this->add_member_i (object_group,
00078                              the_location,
00079                              member,
00080                              check_type_id);
00081 
00082 }
00083 
00084 
00085 PortableGroup::ObjectGroup_ptr
00086 TAO_PG_ObjectGroupManager::_tao_add_member (
00087     PortableGroup::ObjectGroup_ptr object_group,
00088     const PortableGroup::Location & the_location,
00089     CORBA::Object_ptr member,
00090     const char * type_id,
00091     const CORBA::Boolean propagate_member_already_present)
00092 {
00093   if (CORBA::is_nil (member))
00094     throw CORBA::BAD_PARAM ();
00095 
00096   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00097                     guard,
00098                     this->lock_,
00099                     PortableGroup::ObjectGroup::_nil ());
00100 
00101   PortableGroup::ObjectGroup_var new_group;
00102 
00103   try
00104     {
00105       // TypeId already checked by GenericFactory.
00106       const CORBA::Boolean check_type_id = 0;
00107 
00108       new_group = this->add_member_i (object_group,
00109                                       the_location,
00110                                       member,
00111                                       check_type_id);
00112     }
00113   catch (const PortableGroup::ObjectGroupNotFound&)
00114     {
00115       throw CORBA::INTERNAL ();
00116     }
00117   catch (const PortableGroup::MemberAlreadyPresent&)
00118     {
00119       if (propagate_member_already_present)
00120         throw;
00121       else
00122         throw CORBA::INTERNAL ();
00123     }
00124   catch (const PortableGroup::ObjectNotAdded&)
00125     {
00126       throw PortableGroup::NoFactory (the_location, type_id);
00127     }
00128 
00129   return new_group._retn ();
00130 }
00131 
00132 PortableGroup::ObjectGroup_ptr
00133 TAO_PG_ObjectGroupManager::add_member_i (
00134     PortableGroup::ObjectGroup_ptr object_group,
00135     const PortableGroup::Location & the_location,
00136     CORBA::Object_ptr member,
00137     const CORBA::Boolean check_type_id)
00138 {
00139   TAO_PG_ObjectGroup_Map_Entry * group_entry =
00140     this->get_group_entry (object_group);
00141 
00142   if (check_type_id)
00143     {
00144       CORBA::Boolean right_type_id =
00145         this->valid_type_id (object_group,
00146                              group_entry,
00147                              member);
00148 
00149       if (!right_type_id)
00150         {
00151           // The member's type_id does not match the object group's
00152           // type_id.
00153           throw PortableGroup::ObjectNotAdded ();
00154         }
00155     }
00156 
00157   TAO_PG_ObjectGroup_Array * groups = 0;
00158   if (this->location_map_.find (the_location, groups) == 0
00159       && this->member_already_present (*groups, group_entry))
00160     throw PortableGroup::MemberAlreadyPresent ();
00161 
00162   TAO_PG_MemberInfo member_info;
00163   member_info.member   = CORBA::Object::_duplicate (member);
00164   member_info.location = the_location;
00165 
00166   if (groups == 0)
00167     {
00168       ACE_NEW_THROW_EX (groups,
00169                         TAO_PG_ObjectGroup_Array,
00170                         CORBA::NO_MEMORY (
00171                           CORBA::SystemException::_tao_minor_code (
00172                             TAO::VMCID,
00173                             ENOMEM),
00174                           CORBA::COMPLETED_NO));
00175 
00176       auto_ptr<TAO_PG_ObjectGroup_Array> safe_groups (groups);
00177 
00178       // This should not fail!
00179       if (this->location_map_.bind (the_location, groups) != 0)
00180         {
00181           throw PortableGroup::ObjectNotAdded ();
00182         }
00183 
00184       (void) safe_groups.release ();
00185     }
00186 
00187   // No object group member of the object group with the given
00188   // ObjectGroupId resides at the location.  Add the object group
00189   // entry to array of object groups residing at the location.
00190   const size_t groups_len = groups->size ();
00191   groups->size (groups_len + 1);
00192   (*groups)[groups_len] = group_entry;
00193 
00194   // Don't bother checking for duplicates since a check is already
00195   // performed when binding to the location map above.
00196   if (group_entry->member_infos.insert_tail (member_info) != 0)
00197     throw PortableGroup::ObjectNotAdded ();
00198 
00199   return PortableGroup::ObjectGroup::_duplicate (object_group);
00200 }
00201 
00202 PortableGroup::ObjectGroup_ptr
00203 TAO_PG_ObjectGroupManager::remove_member (
00204     PortableGroup::ObjectGroup_ptr object_group,
00205     const PortableGroup::Location & the_location)
00206 {
00207   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->lock_, 0);
00208 
00209   TAO_PG_ObjectGroup_Map_Entry * group_entry =
00210     this->get_group_entry (object_group);
00211 
00212   TAO_PG_ObjectGroup_Array * groups = 0;
00213   if (this->location_map_.find (the_location, groups) != 0)
00214     throw PortableGroup::ObjectGroupNotFound ();
00215 
00216   // Multiple members from different object groups may reside at the
00217   // same location.  Iterate through the list to attempt to find a
00218   // match for the exact object group.
00219   size_t to_be_removed = 0;
00220 
00221   // get the position of the object group in the object_group_array
00222   to_be_removed = this->get_object_group_position (*groups, group_entry);
00223 
00224   // remove the element from the array and resize the array.
00225   const size_t groups_len = groups->size ();
00226   size_t j;
00227   for (size_t i = to_be_removed; i < groups_len - 1; ++i)
00228     {
00229       j = i + 1;
00230       (*groups)[i] = (*groups)[j];
00231     }
00232 
00233   groups->size (groups_len - 1);
00234 
00235   TAO_PG_MemberInfo_Set & member_infos = group_entry->member_infos;
00236 
00237   TAO_PG_MemberInfo_Set::iterator end = member_infos.end ();
00238 
00239   for (TAO_PG_MemberInfo_Set::iterator iter = member_infos.begin ();
00240        iter != end;
00241        ++iter)
00242     {
00243       const TAO_PG_MemberInfo & info = *iter;
00244 
00245       if (info.location == the_location)
00246         {
00247           // Give the GenericFactory a chance to delete a member if
00248           // its membership is under infrastructure control.
00249           if (this->generic_factory_)
00250             {
00251               this->generic_factory_->delete_member (group_entry->group_id,
00252                                                      the_location);
00253             }
00254 
00255           if (member_infos.remove (info) == 0)
00256             {
00257               if (this->generic_factory_)
00258                 {
00259                   this->generic_factory_->check_minimum_number_members (
00260                     object_group,
00261                     group_entry->group_id,
00262                     group_entry->type_id.in ());
00263                 }
00264 
00265               return PortableGroup::ObjectGroup::_duplicate (object_group);
00266             }
00267           else
00268             break;
00269         }
00270     }
00271 
00272   throw PortableGroup::MemberNotFound ();
00273 }
00274 
00275 PortableGroup::Locations *
00276 TAO_PG_ObjectGroupManager::locations_of_members (
00277     PortableGroup::ObjectGroup_ptr object_group)
00278 {
00279   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->lock_, 0);
00280 
00281   TAO_PG_ObjectGroup_Map_Entry * group_entry =
00282     this->get_group_entry (object_group);
00283 
00284   PortableGroup::Locations *temp = 0;
00285   ACE_NEW_THROW_EX (temp,
00286                     PortableGroup::Locations,
00287                     CORBA::NO_MEMORY (
00288                       CORBA::SystemException::_tao_minor_code (
00289                         TAO::VMCID,
00290                         ENOMEM),
00291                       CORBA::COMPLETED_NO));
00292 
00293   PortableGroup::Locations_var locations = temp;
00294 
00295   TAO_PG_MemberInfo_Set & member_infos = group_entry->member_infos;
00296 
00297   locations->length (static_cast<CORBA::ULong> (member_infos.size ()));
00298 
00299   CORBA::ULong loc = 0;
00300   TAO_PG_MemberInfo_Set::iterator end = member_infos.end ();
00301 
00302   for (TAO_PG_MemberInfo_Set::iterator i = member_infos.begin ();
00303        i != end;
00304        ++i)
00305     locations[loc++] = (*i).location;
00306 
00307   return locations._retn ();
00308 }
00309 
00310 PortableGroup::ObjectGroups *
00311 TAO_PG_ObjectGroupManager::groups_at_location (
00312     const PortableGroup::Location & the_location)
00313 {
00314   PortableGroup::ObjectGroups * ogs;
00315   ACE_NEW_THROW_EX (ogs,
00316                     PortableGroup::ObjectGroups,
00317                     CORBA::NO_MEMORY ());
00318 
00319   PortableGroup::ObjectGroups_var object_groups = ogs;
00320 
00321   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->lock_, 0);
00322 
00323   TAO_PG_ObjectGroup_Array * groups;
00324   if (this->location_map_.find (the_location, groups) == 0)
00325     {
00326       CORBA::ULong len = static_cast<CORBA::ULong> (groups->size ());
00327 
00328       ogs->length (len);
00329 
00330       for (CORBA::ULong i = 0; i < len; ++i)
00331         {
00332           object_groups[i] =
00333             PortableGroup::ObjectGroup::_duplicate (
00334               (*groups)[i]->object_group.in ());
00335         }
00336     }
00337 
00338   return object_groups._retn ();
00339 }
00340 
00341 PortableGroup::ObjectGroupId
00342 TAO_PG_ObjectGroupManager::get_object_group_id (
00343     PortableGroup::ObjectGroup_ptr object_group)
00344 {
00345   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00346                     guard,
00347                     this->lock_,
00348                     0);
00349 
00350   TAO_PG_ObjectGroup_Map_Entry * entry =
00351     this->get_group_entry (object_group);
00352 
00353   if (entry == 0)
00354     throw CORBA::INTERNAL ();
00355 
00356   // Only the lower 32 bits of the 64 bit PortableGroup::ObjectGroupId
00357   // are ever used.
00358   return entry->group_id;
00359 }
00360 
00361 PortableGroup::ObjectGroup_ptr
00362 TAO_PG_ObjectGroupManager::get_object_group_ref (
00363     PortableGroup::ObjectGroup_ptr object_group)
00364 {
00365   TAO_PG_ObjectGroup_Map_Entry * entry = 0;
00366 
00367   {
00368     ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00369                       guard,
00370                       this->lock_,
00371                       PortableGroup::ObjectGroup::_nil ());
00372 
00373 
00374     entry = this->get_group_entry (object_group);
00375   }
00376 
00377   if (entry == 0)
00378     throw CORBA::INTERNAL ();
00379 
00380   // This implemenation does not change the object group reference.
00381   return PortableGroup::ObjectGroup::_duplicate (object_group);
00382 }
00383 
00384 CORBA::Object_ptr
00385 TAO_PG_ObjectGroupManager::get_member_ref (
00386     PortableGroup::ObjectGroup_ptr object_group,
00387     const PortableGroup::Location & loc)
00388 {
00389   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00390                     guard,
00391                     this->lock_,
00392                     CORBA::Object::_nil ());
00393 
00394   TAO_PG_ObjectGroup_Map_Entry * group_entry =
00395     this->get_group_entry (object_group);
00396 
00397   // This method assumes that it is faster to check for non-existence
00398   // of an object group (and hence the member) at a given location,
00399   // instead of existence of a member at a given location.
00400 
00401   TAO_PG_ObjectGroup_Array * groups = 0;
00402   if (this->location_map_.find (loc, groups) == 0
00403       && this->member_already_present (*groups, group_entry))
00404     {
00405       TAO_PG_MemberInfo_Set & member_infos = group_entry->member_infos;
00406 
00407       TAO_PG_MemberInfo_Set::iterator end = member_infos.end ();
00408 
00409       // @todo If the object group contains a large number of members,
00410       //       this loop could take a while.  Explore potentially
00411       //       faster containers for the list of PG_MemberInfos in the
00412       //       future.
00413       for (TAO_PG_MemberInfo_Set::iterator i = member_infos.begin ();
00414            i != end;
00415            ++i)
00416         if ((*i).location == loc)
00417           return CORBA::Object::_duplicate ((*i).member.in ());
00418     }
00419 
00420   // No member of the given object group is present at the given
00421   // location.
00422   throw PortableGroup::MemberNotFound ();
00423 }
00424 
00425 PortableGroup::ObjectGroup_ptr
00426 TAO_PG_ObjectGroupManager::get_object_group_ref_from_id (
00427         PortableGroup::ObjectGroupId group_id
00428       )
00429 {
00430   //@@ If we change the PG's concept of ObjectGroupId from
00431   // PortableServer::ObjectId to PortableGroup::ObjectGroupId, can
00432   // just call TAO_PG_ObjectGroupManager::object_group() here.
00433 
00434   TAO_PG_ObjectGroup_Map_Entry * group_entry = 0;
00435   {
00436     ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00437                       guard,
00438                       this->lock_,
00439                       PortableGroup::ObjectGroup::_nil ());
00440 
00441     if (this->object_group_map_.find (ACE_U64_TO_U32 (group_id),
00442                                       group_entry)
00443          != 0)
00444       {
00445         throw PortableGroup::ObjectGroupNotFound ();
00446       }
00447   }
00448 
00449   if (group_entry == 0)
00450     {
00451       throw CORBA::INTERNAL ();
00452     }
00453 
00454   return
00455     PortableGroup::ObjectGroup::_duplicate (group_entry->object_group.in ());
00456 }
00457 
00458 PortableGroup::ObjectGroup_ptr
00459 TAO_PG_ObjectGroupManager::create_object_group (
00460   CORBA::ULong group_id,
00461   const PortableServer::ObjectId &oid,
00462   const char * type_id,
00463   const PortableGroup::Criteria & the_criteria)
00464 {
00465   if (CORBA::is_nil (this->poa_.in ()))
00466     throw CORBA::INTERNAL ();
00467 
00468   // Create a reference for the ObjectGroup corresponding to the
00469   // RepositoryId of the object being created.
00470   CORBA::Object_var object_group =
00471     this->poa_->create_reference_with_id (oid,
00472                                           type_id);
00473 
00474   TAO_PG_ObjectGroup_Map_Entry * group_entry = 0;
00475   ACE_NEW_THROW_EX (group_entry,
00476                     TAO_PG_ObjectGroup_Map_Entry,
00477                     CORBA::NO_MEMORY (
00478                       CORBA::SystemException::_tao_minor_code (
00479                         TAO::VMCID,
00480                         ENOMEM),
00481                       CORBA::COMPLETED_NO));
00482 
00483   auto_ptr<TAO_PG_ObjectGroup_Map_Entry> safe_group_entry (group_entry);
00484 
00485   // Set the RepositoryId associated with the created ObjectGroup_Map
00486   // entry.
00487   group_entry->type_id = CORBA::string_dup (type_id);
00488 
00489   group_entry->group_id = group_id;
00490 
00491   group_entry->object_group = object_group;
00492 
00493   CORBA::ULong len = the_criteria.length ();
00494   group_entry->properties.length (len);
00495   for (CORBA::ULong i = 0; i < len; ++i)
00496     group_entry->properties[i] = the_criteria[i];
00497 
00498   {
00499     ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00500                       guard,
00501                       this->lock_,
00502                       0);
00503 
00504     if (this->object_group_map_.bind (oid, group_entry) != 0)
00505       throw PortableGroup::ObjectNotCreated ();
00506   }
00507 
00508   (void) safe_group_entry.release ();
00509 
00510   return object_group._retn ();
00511 }
00512 
00513 void
00514 TAO_PG_ObjectGroupManager::destroy_object_group (
00515   const PortableServer::ObjectId & oid)
00516 {
00517   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00518 
00519   TAO_PG_ObjectGroup_Map_Entry * group_entry = 0;
00520   if (this->object_group_map_.unbind (oid, group_entry) != 0)
00521     throw PortableGroup::ObjectNotFound ();
00522 
00523   delete group_entry;
00524 }
00525 
00526 char *
00527 TAO_PG_ObjectGroupManager::type_id (
00528   PortableGroup::ObjectGroup_ptr object_group)
00529 {
00530   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00531                     guard,
00532                     this->lock_,
00533                     0);
00534 
00535   TAO_PG_ObjectGroup_Map_Entry * group_entry =
00536     this->get_group_entry (object_group);
00537 
00538   return CORBA::string_dup (group_entry->type_id.in ());
00539 }
00540 
00541 PortableGroup::ObjectGroup_ptr
00542 TAO_PG_ObjectGroupManager::object_group (const PortableServer::ObjectId & oid)
00543 {
00544   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00545                     guard,
00546                     this->lock_,
00547                     PortableGroup::ObjectGroup::_nil ());
00548 
00549   TAO_PG_ObjectGroup_Map_Entry * group_entry = 0;
00550   if (this->object_group_map_.find (oid, group_entry) == 0)
00551     return
00552       PortableGroup::ObjectGroup::_duplicate (group_entry->object_group.in ());
00553   else
00554     return PortableGroup::ObjectGroup::_nil ();
00555 }
00556 
00557 CORBA::ULong
00558 TAO_PG_ObjectGroupManager::member_count (
00559     PortableGroup::ObjectGroup_ptr group)
00560 {
00561 //   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00562 //                     guard,
00563 //                     this->lock_,
00564 //                     0);
00565 
00566   TAO_PG_ObjectGroup_Map_Entry * group_entry =
00567     this->get_group_entry (group);
00568 
00569   return static_cast<CORBA::ULong> (group_entry->member_infos.size ());
00570 }
00571 
00572 void
00573 TAO_PG_ObjectGroupManager::poa (PortableServer::POA_ptr p)
00574 {
00575   this->poa_ = PortableServer::POA::_duplicate (p);
00576 }
00577 
00578 
00579 PortableGroup::Properties *
00580 TAO_PG_ObjectGroupManager::get_properties (
00581     PortableGroup::ObjectGroup_ptr object_group)
00582 {
00583   PortableGroup::Properties * properties = 0;
00584   ACE_NEW_THROW_EX (properties,
00585                     PortableGroup::Properties,
00586                     CORBA::NO_MEMORY (
00587                       CORBA::SystemException::_tao_minor_code (
00588                         TAO::VMCID,
00589                         ENOMEM),
00590                       CORBA::COMPLETED_NO));
00591 
00592   PortableGroup::Properties_var safe_properties = properties;
00593 
00594   {
00595     ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00596                       guard,
00597                       this->lock_,
00598                       0);
00599 
00600     TAO_PG_ObjectGroup_Map_Entry * group_entry =
00601       this->get_group_entry (object_group);
00602 
00603     *properties = group_entry->properties;
00604   }
00605 
00606   return safe_properties._retn ();
00607 }
00608 
00609 TAO_PG_ObjectGroup_Map_Entry *
00610 TAO_PG_ObjectGroupManager::get_group_entry (
00611     CORBA::Object_ptr object_group)
00612 {
00613   if (CORBA::is_nil (this->poa_.in ()))
00614     throw CORBA::INTERNAL ();
00615 
00616   PortableServer::ObjectId_var oid;
00617   try
00618     {
00619       oid = this->poa_->reference_to_id (object_group);
00620     }
00621   catch (const PortableServer::POA::WrongAdapter& ex)
00622     {
00623       if (TAO_debug_level > 0)
00624         ex._tao_print_exception ("TAO_PG (%P|%t) Unexpected exception\n");
00625 
00626       throw CORBA::INTERNAL ();
00627     }
00628   catch (const PortableServer::POA::WrongPolicy& ex)
00629     {
00630       if (TAO_debug_level > 0)
00631         ex._tao_print_exception ("TAO_PG (%P|%t) Unexpected exception\n");
00632 
00633       throw CORBA::INTERNAL ();
00634     }
00635 
00636   TAO_PG_ObjectGroup_Map_Entry * group_entry = 0;
00637   if (this->object_group_map_.find (oid.in (), group_entry) != 0)
00638     throw PortableGroup::ObjectGroupNotFound ();
00639 
00640   return group_entry;
00641 }
00642 
00643 CORBA::Boolean
00644 TAO_PG_ObjectGroupManager::member_already_present (
00645   const TAO_PG_ObjectGroup_Array &groups,
00646   TAO_PG_ObjectGroup_Map_Entry * group_entry)
00647 {
00648   // Multiple members from different object groups may reside at the
00649   // same location.  Iterate through the list to attempt to find a
00650   // match.
00651   size_t len = groups.size ();
00652   for (size_t i = 0; i < len; ++i)
00653     {
00654       // It should be enough just to compare the group_entry pointers,
00655       // but that seems brittle.  Better to check a controlled value,
00656       // like the ObjectGroupId.
00657       if (groups[i]->group_id == group_entry->group_id)
00658         {
00659           // Member with given type ID exists at the given
00660           // location.
00661           return 1;
00662         }
00663     }
00664 
00665   // No member with given type ID present at the given location.
00666   return 0;
00667 }
00668 
00669 size_t
00670 TAO_PG_ObjectGroupManager::get_object_group_position (
00671   const TAO_PG_ObjectGroup_Array &groups,
00672   TAO_PG_ObjectGroup_Map_Entry * group_entry)
00673 {
00674   // Multiple members from different object groups may reside at the
00675   // same location.  Iterate through the list to attempt to find a
00676   // match.
00677   size_t len = groups.size ();
00678   for (size_t i = 0; i < len; ++i)
00679     {
00680       // It should be enough just to compare the group_entry pointers,
00681       // but that seems brittle.  Better to check a controlled value,
00682       // like the ObjectGroupId.
00683       if (groups[i]->group_id == group_entry->group_id)
00684         {
00685           // Member with given type ID exists at the given
00686           // location.
00687           return i;
00688         }
00689     }
00690 
00691   // No member with given type ID present at the given location.
00692   return 0;
00693 }
00694 
00695 CORBA::Boolean
00696 TAO_PG_ObjectGroupManager::valid_type_id (
00697   PortableGroup::ObjectGroup_ptr object_group,
00698   TAO_PG_ObjectGroup_Map_Entry * group_entry,
00699   CORBA::Object_ptr member)
00700 {
00701   // @todo Strategize this -- e.g. strict type checking.
00702 
00703   if (CORBA::is_nil (member))
00704     throw CORBA::BAD_PARAM ();
00705 
00706   // Before we can use this code, i.e. the reverse lock, the
00707   // TAO_PG_ObjectGroup_Entry should be made so that it is reference
00708   // counted.  This is necessary since releasing the lock would
00709   // allow other threads to destroy/unbind the object group entry.
00710   // Another alternative is to simply attempt to reacquire the
00711   // object group map entry once the lock is reacquired, which is
00712   // easier to implement.
00713 
00714   // Copy the type_id before releasing the lock to avoid a race
00715   // condition.
00716   CORBA::String_var type_id =
00717     CORBA::string_dup (group_entry->type_id.in ());
00718 
00719   CORBA::Boolean right_type_id = 0;
00720   {
00721     // Release the lock during the type_id check.  No need to block
00722     // other threads during the invocation.
00723     ACE_Reverse_Lock<TAO_SYNCH_MUTEX> reverse_lock (this->lock_);
00724 
00725     ACE_GUARD_RETURN (ACE_Reverse_Lock<TAO_SYNCH_MUTEX>,
00726                       reverse_guard,
00727                       reverse_lock,
00728                       right_type_id);
00729 
00730     // Make sure an Object of the correct type was created.  It is
00731     // possible that an object of the wrong type was created if the
00732     // type_id parameter does not match the type of object the
00733     // GenericFactory creates.
00734     right_type_id =
00735       member->_is_a (type_id.in ());
00736   }
00737 
00738   // Make sure the group entry still exists.  It may have been
00739   // destroyed by another thread.
00740   group_entry = this->get_group_entry (object_group);
00741 
00742   return right_type_id;
00743 }
00744 
00745 void
00746 TAO_PG_ObjectGroupManager::generic_factory (
00747   TAO_PG_GenericFactory * generic_factory)
00748 {
00749   this->generic_factory_ = generic_factory;
00750 }
00751 
00752 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:49:50 2010 for TAO_PortableGroup by  doxygen 1.4.7