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

Generated on Thu Nov 9 14:03:33 2006 for TAO_PortableGroup by doxygen 1.3.6