PG_Object_Group.cpp

Go to the documentation of this file.
00001 // PG_Object_Group.cpp,v 1.22 2006/03/22 17:04:37 jwillemsen Exp
00002 
00003 #include "orbsvcs/PortableGroup/PG_Object_Group.h"
00004 #include "orbsvcs/PortableGroup/PG_conf.h"
00005 
00006 #include "orbsvcs/PortableGroup/PG_Operators.h" // Borrow operator== on CosNaming::Name
00007 #include "orbsvcs/PortableGroup/PG_Utils.h"
00008 
00009 #include "tao/debug.h"
00010 
00011 #include "ace/Get_Opt.h"
00012 #include "ace/Vector_T.h"
00013 
00014 
00015 // Borland Developer Studio 2006 and earlier give a warning about comparing
00016 // signed and unsigned values in the minimum_polulate() and
00017 // initial_populate() warnings. The comparison uses a unsigned long and
00018 // unsigned short and it seems that the compiler promotes the unsigned
00019 // short of an int and this then gives the warning. Just for Borland
00020 // disabled the warning in this file.
00021 #if defined (__BORLANDC__) && (__BORLANDC__ <= 0x582)
00022 # pragma option push -w-csu
00023 # pragma nopushoptwarn
00024 # pragma nopackwarning
00025 #endif /* __BORLANDC__ && __BORLANDC__ <= 0x582 */
00026 
00027 #define TODO int todo;
00028 
00029 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00030 
00031 TAO::PG_Object_Group::MemberInfo::MemberInfo (
00032     CORBA::Object_ptr member,
00033     const PortableGroup::Location & location)
00034   : member_ (CORBA::Object::_duplicate (member))
00035   , factory_(PortableGroup::GenericFactory::_nil ())
00036   , location_ (location)
00037   , is_primary_ (0)
00038 {
00039 }
00040 
00041 TAO::PG_Object_Group::MemberInfo::MemberInfo (
00042     CORBA::Object_ptr member,
00043     const PortableGroup::Location & location,
00044     PortableGroup::GenericFactory_ptr factory,
00045     PortableGroup::GenericFactory::FactoryCreationId factory_id)
00046   : member_ (CORBA::Object::_duplicate (member))
00047   , factory_ (PortableGroup::GenericFactory::_duplicate (factory))
00048   , factory_id_ (factory_id)
00049   , location_ (location)
00050   , is_primary_ (0)
00051 {
00052 }
00053 
00054 TAO::PG_Object_Group::MemberInfo::~MemberInfo (void)
00055 {
00056   if( ! CORBA::is_nil (this->factory_.in()))
00057     {
00058       this->factory_->delete_object (this->factory_id_);
00059     }
00060 }
00061 
00062 
00063 TAO::PG_Object_Group::PG_Object_Group (
00064   CORBA::ORB_ptr orb,
00065   PortableGroup::FactoryRegistry_ptr factory_registry,
00066   TAO::PG_Object_Group_Manipulator & manipulator,
00067   CORBA::Object_ptr empty_group,
00068   const PortableGroup::TagGroupTaggedComponent & tagged_component,
00069   const char * type_id,
00070   const PortableGroup::Criteria & the_criteria,
00071   TAO::PG_Property_Set * type_properties)
00072   : internals_()
00073   , orb_ (CORBA::ORB::_duplicate (orb))
00074   , factory_registry_ (PortableGroup::FactoryRegistry::_duplicate (factory_registry))
00075   , manipulator_ (manipulator)
00076   , empty_ (1)
00077   , role_ (type_id)
00078   , type_id_ (CORBA::string_dup (type_id))
00079   , tagged_component_ (tagged_component)
00080   , reference_ (CORBA::Object::_duplicate(empty_group))
00081   , members_ ()
00082   , primary_location_(0)
00083   , properties_ (the_criteria, type_properties)
00084   , initial_number_members_ (0)
00085   , minimum_number_members_ (0)
00086   , group_specific_factories_ ()
00087 {
00088 }
00089 
00090 TAO::PG_Object_Group::~PG_Object_Group (void)
00091 {
00092   for (MemberMap_Iterator it = this->members_.begin();
00093       it != this->members_.end();
00094       ++it)
00095     {
00096       MemberInfo * member = (*it).int_id_;
00097       delete member;
00098     }
00099   this->members_.unbind_all ();
00100 }
00101 
00102 #if 0   // may want this again someday
00103 /////////////////////
00104 // q&d debug function
00105 static void
00106 dump_ior (const char * base,
00107           const char * ext,
00108           unsigned long version,
00109           const char * iogr)
00110 {
00111   char filename[1000];
00112   ACE_OS::sprintf(filename, "%s_%lu.%s", base, version, ext );
00113 
00114   FILE * iorfile = ACE_OS::fopen(filename, "w");
00115   ACE_OS::fwrite (iogr, 1, ACE_OS::strlen(iogr), iorfile);
00116   ACE_OS::fclose (iorfile);
00117 }
00118 #endif  // may want this again someday
00119 
00120 PortableGroup::ObjectGroup_ptr
00121 TAO::PG_Object_Group::reference (void) const
00122 {
00123   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00124                     guard,
00125                     this->internals_,
00126                     PortableGroup::ObjectGroup::_nil ());
00127   return PortableGroup::ObjectGroup::_duplicate (this->reference_);
00128 }
00129 
00130 void
00131 TAO::PG_Object_Group::get_group_specific_factories (
00132   PortableGroup::FactoryInfos & result) const
00133 {
00134   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00135 
00136   // copy is needed to have some semblance of thread safeness.
00137   // if performance is an issue avoid this method.
00138   result = this->group_specific_factories_;
00139 }
00140 
00141 const PortableGroup::Location &
00142 TAO::PG_Object_Group::get_primary_location (void) const
00143 {
00144   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00145                     guard,
00146                     this->internals_,
00147                     this->primary_location_);
00148   return this->primary_location_;
00149 }
00150 
00151 
00152 PortableGroup::ObjectGroup_ptr
00153 TAO::PG_Object_Group::add_member_to_iogr (CORBA::Object_ptr member
00154                                           ACE_ENV_ARG_DECL)
00155 {
00156   // assume internals is locked
00157 
00158   PortableGroup::ObjectGroup_var result;
00159 
00160  ////////////////////////////
00161   // @@ HACK ALERT
00162   // The PortableGroup::ObjectGroupManager creates an object reference
00163   // containing a dummy entry so it will have a place to store the
00164   // tagged group component. If this is the first entry, we need to
00165   // remove that entry once we have a *real* member. This can be
00166   // avoided when we get support for TAG_MULTIPLE_COMPONENTS.   For
00167   // now, we already have a copy of the tagGroupTagged component and
00168   // we're going to use it below wen we increment the group version so
00169   // we can clean out the dummy entry.
00170   PortableGroup::ObjectGroup_var cleaned =
00171     PortableGroup::ObjectGroup::_duplicate (this->reference_.in ());
00172   if (this->empty_)
00173     {
00174       // remove the original profile.  It's a dummy entry supplied by
00175       // create_object.
00176       cleaned =
00177         this->manipulator_.remove_profiles (cleaned.in (),
00178                                             this->reference_.in ()
00179                                             ACE_ENV_ARG_PARAMETER);
00180       ACE_CHECK_RETURN (PortableGroup::ObjectGroup::_nil());
00181       this->empty_ = 0;
00182     }
00183 
00184   // create a list of references to be merged
00185   TAO_IOP::TAO_IOR_Manipulation::IORList iors (2);
00186   iors.length (2);
00187   iors [0] = CORBA::Object::_duplicate (cleaned.in());
00188   iors [1] = CORBA::Object::_duplicate (member);
00189 
00190   // Now merge the list into one new IOGR
00191   result =
00192     this->manipulator_.merge_iors (iors ACE_ENV_ARG_PARAMETER);
00193   ACE_CHECK_RETURN (PortableGroup::ObjectGroup::_nil ());
00194   return result._retn ();
00195 }
00196 
00197 void
00198 TAO::PG_Object_Group::add_member (const PortableGroup::Location & the_location,
00199                                   CORBA::Object_ptr member
00200                                   ACE_ENV_ARG_DECL)
00201   ACE_THROW_SPEC ((CORBA::SystemException,
00202                    PortableGroup::ObjectNotAdded))
00203 
00204 {
00205   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00206 
00207   /////////////////////////////////////////
00208   // Convert the new member to a string IOR
00209   // This keeps a clean IOR (not an IOGR!)
00210   // while we add it to a group.  We need a
00211   // IORs, not IOGRs to send new IOGRs out
00212   // to replicas.
00213 
00214   CORBA::String_var member_ior_string =
00215     orb_->object_to_string (member
00216                             ACE_ENV_ARG_PARAMETER);
00217   ACE_CHECK;
00218 
00219   PortableGroup::ObjectGroup_var new_reference =
00220     add_member_to_iogr (member
00221                         ACE_ENV_ARG_PARAMETER);
00222   ACE_CHECK;
00223 
00224   // Convert new member back to a (non group) ior.
00225   CORBA::Object_var member_ior =
00226     this->orb_->string_to_object (member_ior_string.in ()
00227                                   ACE_ENV_ARG_PARAMETER);
00228   ACE_CHECK;
00229 
00230   MemberInfo * info = 0;
00231   ACE_NEW_THROW_EX (info,
00232                     MemberInfo (member_ior.in (),
00233                                 the_location),
00234                     CORBA::NO_MEMORY());
00235 
00236   if (this->members_.bind (the_location, info) != 0)
00237     {
00238       // @@ Dale why this is a NO MEMORY exception?
00239       ACE_THROW(CORBA::NO_MEMORY());
00240     }
00241 
00242   this->reference_ = new_reference; // note var-to-var assignment does
00243                                     // a duplicate
00244   if (this->increment_version ())
00245     {
00246       this->distribute_iogr (ACE_ENV_SINGLE_ARG_PARAMETER);
00247       ACE_CHECK;
00248     }
00249   else
00250     {
00251       ACE_THROW (PortableGroup::ObjectNotAdded ());
00252     }
00253 
00254   if (TAO_debug_level > 6)
00255     {
00256       ACE_DEBUG ((LM_DEBUG,
00257                   ACE_TEXT("PG (%P|%t) exit Object_Group add_member \n")));
00258     }
00259 }
00260 
00261 int
00262 TAO::PG_Object_Group::set_primary_member (
00263     TAO_IOP::TAO_IOR_Property * prop,
00264     const PortableGroup::Location & the_location
00265     ACE_ENV_ARG_DECL)
00266   ACE_THROW_SPEC ((CORBA::SystemException,
00267                    PortableGroup::MemberNotFound))
00268 {
00269   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00270                     guard,
00271                     this->internals_,
00272                     0);
00273   int result = 1;
00274   MemberInfo * info = 0;
00275   if (this->members_.find (the_location, info) == 0)
00276     {
00277       int cleared = 0;
00278       this->primary_location_ = the_location;
00279       for (MemberMap_Iterator it = this->members_.begin();
00280            !cleared && it != this->members_.end();
00281            ++it)
00282         {
00283           cleared = (*it).int_id_->is_primary_;
00284           (*it).int_id_->is_primary_ = 0;
00285         }
00286       info->is_primary_ = 1;
00287 
00288       int set_ok =
00289         this->manipulator_.set_primary (prop,
00290                                         this->reference_.in (),
00291                                         info->member_.in ()
00292                                         ACE_ENV_ARG_PARAMETER);
00293       ACE_CHECK_RETURN (0);
00294       if (!set_ok)
00295         {
00296           if (TAO_debug_level > 3)
00297             {
00298               ACE_ERROR ((LM_ERROR,
00299                           ACE_TEXT ("%T %n (%P|%t) - ")
00300                           ACE_TEXT ("Can't set primary in IOGR .\n")
00301                           ));
00302             }
00303 //@@: ACE_THROW (FT::PrimaryNotSet());
00304           result = 0;
00305         }
00306 
00307       if (result && this->increment_version ())
00308         {
00309           this->distribute_iogr (ACE_ENV_SINGLE_ARG_PARAMETER);
00310           ACE_CHECK_RETURN (0);
00311         }
00312       else
00313         {
00314           if (TAO_debug_level > 3)
00315             {
00316               ACE_DEBUG ((LM_DEBUG,
00317                           ACE_TEXT("TAO-PG (%P|%t) - set_primary_location ")
00318                           ACE_TEXT("throwing PrimaryNotSet because increment")
00319                           ACE_TEXT("version failed.\n")
00320                           ));
00321             }
00322 //@@: ACE_THROW (FT::PrimaryNotSet());
00323           result = 0;
00324         }
00325     }
00326   else
00327     {
00328       if (TAO_debug_level > 3)
00329         {
00330           ACE_DEBUG ((LM_DEBUG,
00331                       ACE_TEXT ("TAO-PG (%P|%t) - set_primary_location ")
00332                       ACE_TEXT ("throwing MemberNotFound.\n")));
00333         }
00334       ACE_THROW_RETURN (PortableGroup::MemberNotFound(),
00335                         -1);
00336     }
00337 
00338   return result;
00339 }
00340 
00341 
00342 void
00343 TAO::PG_Object_Group::remove_member (
00344     const PortableGroup::Location & the_location
00345     ACE_ENV_ARG_DECL)
00346   ACE_THROW_SPEC ( (CORBA::SystemException,
00347                    PortableGroup::MemberNotFound))
00348 {
00349   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00350   MemberInfo * info = 0;
00351   if (this->members_.unbind (the_location, info) == 0)
00352     {
00353       if (this->members_.current_size() > 0)
00354         {
00355           this->reference_ =
00356             this->manipulator_.remove_profiles (this->reference_.in (),
00357                                                 info->member_.in ()
00358                                                 ACE_ENV_ARG_PARAMETER);
00359           ACE_CHECK;
00360         }
00361       else
00362         {
00363           empty_ = 1;
00364         }
00365 
00366       delete info;
00367 
00368       if (the_location == this->primary_location_)
00369         {
00370           this->primary_location_.length(0);
00371         }
00372 
00373       if (this->increment_version ())
00374         {
00375           this->distribute_iogr (ACE_ENV_SINGLE_ARG_PARAMETER);
00376           ACE_CHECK;
00377         }
00378 
00379     }
00380   else
00381     {
00382       if (TAO_debug_level > 6)
00383         {
00384           ACE_DEBUG ((LM_DEBUG,
00385                       "TAO-PG (%P|%t) - "
00386                       "remove_member throwing MemberNotFound.\n"
00387                       ));
00388         }
00389       ACE_THROW (PortableGroup::MemberNotFound() );
00390     }
00391 }
00392 
00393 
00394 PortableGroup::ObjectGroupId
00395 TAO::PG_Object_Group::get_object_group_id (void) const
00396 {
00397   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00398                     guard,
00399                     this->internals_,
00400                     0);
00401   return this->tagged_component_.object_group_id;
00402 }
00403 
00404 void
00405 TAO::PG_Object_Group::set_properties_dynamically (
00406     const PortableGroup::Properties & overrides
00407     ACE_ENV_ARG_DECL)
00408   ACE_THROW_SPEC ((CORBA::SystemException,
00409                    PortableGroup::InvalidProperty,
00410                    PortableGroup::UnsupportedProperty))
00411 {
00412   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00413 
00414   this->properties_.decode (overrides ACE_ENV_ARG_PARAMETER);
00415 
00416   //@@ int todo_override_rather_than_replace?
00417 }
00418 
00419 void
00420 TAO::PG_Object_Group::get_properties (
00421     PortableGroup::Properties_var & result) const
00422   ACE_THROW_SPEC ((CORBA::SystemException))
00423 {
00424   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00425   this->properties_.export_properties(*result);
00426 }
00427 
00428 
00429 PortableGroup::TypeId
00430 TAO::PG_Object_Group::get_type_id (void) const
00431 {
00432   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00433                     guard,
00434                     this->internals_,
00435                     0);
00436   return CORBA::string_dup (this->type_id_);
00437 }
00438 
00439 
00440 ///////////////////
00441 // Internal method
00442 
00443 int
00444 TAO::PG_Object_Group::increment_version (void)
00445 {
00446   // assume internals is locked
00447   int result = 0;
00448   this->tagged_component_.object_group_ref_version += 1;
00449   if (TAO_debug_level > 3)
00450     {
00451       ACE_DEBUG ((LM_DEBUG,
00452                   ACE_TEXT ("%T %n (%P|%t) - Setting IOGR version to %u\n"),
00453                   static_cast<unsigned> (this->tagged_component_.object_group_ref_version)
00454                   ));
00455     }
00456 
00457   // Set the version
00458   if (TAO::PG_Utils::set_tagged_component (this->reference_,
00459                                            this->tagged_component_))
00460     {
00461       result = 1;
00462     }
00463   return result;
00464 }
00465 
00466 
00467 //////////////////
00468 // Internal method
00469 void
00470 TAO::PG_Object_Group::distribute_iogr (ACE_ENV_SINGLE_ARG_DECL)
00471 {
00472   // assume internals is locked
00473   CORBA::String_var iogr =
00474     this->orb_->object_to_string (this->reference_.in()
00475                                   ACE_ENV_ARG_PARAMETER);
00476   ACE_CHECK;
00477 
00478 //  size_t n_rep = 0; // for dump_ior below
00479   for (MemberMap_Iterator it = this->members_.begin();
00480        it != this->members_.end ();
00481        ++it)
00482     {
00483       MemberInfo const * info = (*it).int_id_;
00484       //
00485       // Unchecked narrow means the member doesn't have to actually implement the TAO_UpdateObjectGroup interface
00486       // PortableGroup::TAO_UpdateObjectGroup_var uog = PortableGroup::TAO_UpdateObjectGroup::_unchecked_narrow ( info->member_);
00487       // but it doesn work: error message at replica is:
00488       // TAO-FT (2996|976) - Wrong version information within the interceptor [1 | 0]
00489       // TAO_Perfect_Hash_OpTable:find for operation 'tao_update_object_group' (length=23) failed
00490       // back to using _narrow
00491       PortableGroup::TAO_UpdateObjectGroup_var uog =
00492         PortableGroup::TAO_UpdateObjectGroup::_narrow ( info->member_.in ());
00493       if (!CORBA::is_nil (uog.in ()))
00494         {
00495           ACE_TRY_NEW_ENV
00496             {
00497               if (TAO_debug_level > 3)
00498                 {
00499                   ACE_DEBUG ((LM_DEBUG,
00500                               "PG (%P|%t) -  Object_Group pushing "
00501                               "IOGR to %s member: %s@%s.\n",
00502                               (info->is_primary_ ? "Primary" : "Backup"),
00503                               this->role_.c_str (),
00504                               static_cast<const char *> (info->location_[0].id)
00505                               ));
00506                 }
00507               //        dump_ior ("group", "iogr", this->tagged_component_.object_group_ref_version, iogr);
00508               //        CORBA::String_var replica_ior = this->orb_->object_to_string(uog.in() ACE_ENV_ARG_PARAMETER);
00509               //        dump_ior (info->location_[0].id, "ior", (this->tagged_component_.object_group_ref_version * 100) + n_rep++, replica_ior);
00510               uog->tao_update_object_group (iogr.in (),
00511                                             this->tagged_component_.object_group_ref_version,
00512                                             info->is_primary_
00513                                             ACE_ENV_ARG_PARAMETER);
00514               ACE_TRY_CHECK;
00515             }
00516           ACE_CATCHANY
00517             {
00518               // we expect an exception
00519               // tao_update_object_group is not a real method
00520             }
00521           ACE_ENDTRY;
00522         }
00523       else
00524         {
00525           ACE_ERROR ((LM_ERROR,
00526                       "TAO::PG_Object_Group::distribute iogr can't "
00527                       "narrow member reference to "
00528                       "PortableGroup::TAO_UpdateObjectGroup.\n"
00529                       ));
00530         }
00531     }
00532 }
00533 
00534 PortableGroup::Locations *
00535 TAO::PG_Object_Group::locations_of_members (ACE_ENV_SINGLE_ARG_DECL)
00536   ACE_THROW_SPEC ((CORBA::SystemException))
00537 {
00538   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00539                     guard,
00540                     this->internals_,
00541                     0);
00542 
00543   PortableGroup::Locations * result = 0;
00544 
00545   size_t count = this->members_.current_size ();
00546 
00547   ACE_NEW_THROW_EX (
00548     result,
00549     PortableGroup::Locations (count),
00550     CORBA::NO_MEMORY() );
00551   ACE_CHECK_RETURN (0);
00552 
00553   result->length (count);
00554 
00555   size_t pos = 0;
00556   for (MemberMap_Iterator it = this->members_.begin();
00557       it != this->members_.end();
00558       ++it)
00559   {
00560     const PortableGroup::Location & location = (*it).ext_id_;
00561     PortableGroup::Location & out = (*result)[pos];
00562     out = location;
00563   }
00564   return result;
00565 }
00566 
00567 CORBA::Object_ptr
00568 TAO::PG_Object_Group::get_member_reference (
00569     const PortableGroup::Location & the_location
00570     ACE_ENV_ARG_DECL)
00571   ACE_THROW_SPEC ((
00572     CORBA::SystemException,
00573     PortableGroup::MemberNotFound))
00574 {
00575   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00576                     guard,
00577                     this->internals_,
00578                     CORBA::Object::_nil ());
00579 
00580   CORBA::Object_var result;
00581 
00582   MemberInfo * info = 0;
00583   if (this->members_.find (the_location, info) == 0)
00584     {
00585       result = CORBA::Object::_duplicate (info->member_.in ());
00586     }
00587   else
00588     {
00589       ACE_THROW_RETURN (PortableGroup::MemberNotFound(), result._retn ());
00590     }
00591   return result._retn ();
00592 }
00593 
00594 
00595 PortableGroup::MembershipStyleValue
00596 TAO::PG_Object_Group::get_membership_style (void) const
00597 {
00598   PortableGroup::MembershipStyleValue membership_style = 0;
00599   if (!TAO::find (properties_,
00600                   PortableGroup::PG_MEMBERSHIP_STYLE,
00601                   membership_style))
00602     {
00603       membership_style = TAO_PG_MEMBERSHIP_STYLE;
00604     }
00605   return membership_style;
00606 }
00607 
00608 
00609 PortableGroup::MinimumNumberMembersValue
00610 TAO::PG_Object_Group::get_minimum_number_members (void) const
00611 {
00612   PortableGroup::MinimumNumberMembersValue minimum_number_members = 0;
00613   if (!TAO::find (properties_,
00614                   PortableGroup::PG_MINIMUM_NUMBER_MEMBERS,
00615                   minimum_number_members))
00616     {
00617       minimum_number_members = TAO_PG_MINIMUM_NUMBER_MEMBERS;
00618     }
00619   return minimum_number_members;
00620 }
00621 
00622 PortableGroup::InitialNumberMembersValue
00623 TAO::PG_Object_Group::get_initial_number_members (void) const
00624 {
00625   PortableGroup::InitialNumberMembersValue initial_number_members = 0;
00626   if (!TAO::find (properties_,
00627                   PortableGroup::PG_INITIAL_NUMBER_MEMBERS,
00628                   initial_number_members))
00629     {
00630       initial_number_members = TAO_PG_INITIAL_NUMBER_MEMBERS;
00631     }
00632   return initial_number_members;
00633 }
00634 
00635 void
00636 TAO::PG_Object_Group::create_member (
00637     const PortableGroup::Location & the_location,
00638     const char * type_id,
00639     const PortableGroup::Criteria & the_criteria
00640     ACE_ENV_ARG_DECL)
00641   ACE_THROW_SPEC ( (CORBA::SystemException,
00642     PortableGroup::MemberAlreadyPresent,
00643     PortableGroup::NoFactory,
00644     PortableGroup::ObjectNotCreated,
00645     PortableGroup::InvalidCriteria,
00646     PortableGroup::CannotMeetCriteria))
00647 {
00648   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00649 
00650 
00651   if (0 != this->members_.find (the_location))
00652     {
00653       // @@ what if factories were passed as criteria?
00654 
00655       CORBA::String_var factory_type;
00656       PortableGroup::FactoryInfos_var factories =
00657         this->factory_registry_->list_factories_by_role (
00658           role_.c_str(),
00659           factory_type.out ()
00660           ACE_ENV_ARG_PARAMETER);
00661       ACE_CHECK;
00662 
00663       // @@ what if factory_type != type_id != this->type_id_
00664 
00665       int created = 0; // bool
00666       CORBA::ULong factory_count = factories->length ();
00667       for (CORBA::ULong factory_pos = 0;
00668            ! created && factory_pos < factory_count;
00669            ++factory_pos)
00670         {
00671           const PortableGroup::FactoryInfo & factory_info =
00672             (*factories)[factory_pos];
00673           if (factory_info.the_location == the_location)
00674             {
00675               // @@ should we merge the_criteria with
00676               // factory_info.the_criteria?
00677 
00678               PortableGroup::GenericFactory::FactoryCreationId_var fcid;
00679               CORBA::Object_var member =
00680                 factory_info.the_factory->create_object (
00681                   type_id,
00682                   the_criteria,
00683                   fcid. out()
00684                   ACE_ENV_ARG_PARAMETER);
00685               ACE_CHECK;
00686 
00687               // convert the new member to a stringified IOR to avoid
00688               // contamination with group info
00689               CORBA::String_var member_ior_string =
00690                 orb_->object_to_string (member.in ()
00691                                         ACE_ENV_ARG_PARAMETER);
00692               ACE_CHECK;
00693 
00694               PortableGroup::ObjectGroup_var new_reference =
00695                 this->add_member_to_iogr (member.in ()
00696                                           ACE_ENV_ARG_PARAMETER);
00697               ACE_CHECK;
00698 
00699               // Convert new member back to a (non group) ior.
00700               CORBA::Object_var member_ior =
00701                 this->orb_->string_to_object (member_ior_string.in ()
00702                                               ACE_ENV_ARG_PARAMETER);
00703               ACE_CHECK;
00704 
00705               MemberInfo * info = 0;
00706               ACE_NEW_THROW_EX (info, MemberInfo(
00707                                                  member_ior.in(),
00708                                                  the_location,
00709                                                  factory_info.the_factory,
00710                                                  fcid.in ()),
00711                                 CORBA::NO_MEMORY());
00712               ACE_CHECK;
00713 
00714               if (this->members_.bind (the_location, info) != 0)
00715                 {
00716                   ACE_THROW(CORBA::NO_MEMORY());
00717                 }
00718 
00719               this->reference_ = new_reference; // note var-to-var
00720                                                 // assignment does a
00721                                                 // duplicate
00722               if (this->increment_version ())
00723                 {
00724                   this->distribute_iogr (ACE_ENV_SINGLE_ARG_PARAMETER);
00725                   ACE_CHECK;
00726                 }
00727               created = 1;
00728             }
00729         }
00730       if (! created)
00731         {
00732           ACE_THROW (PortableGroup::NoFactory ());
00733         }
00734     }
00735   else
00736     {
00737       ACE_THROW (PortableGroup::MemberAlreadyPresent ());
00738     }
00739 }
00740 
00741 void
00742 TAO::PG_Object_Group::create_members (size_t count ACE_ENV_ARG_DECL)
00743   ACE_THROW_SPEC ((CORBA::SystemException,
00744                    PortableGroup::NoFactory))
00745 {
00746   // assume internals is locked
00747   // @@ what if factories were passed as criteria?
00748 
00749   CORBA::String_var factory_type;
00750   PortableGroup::FactoryInfos_var factories =
00751   this->factory_registry_->list_factories_by_role (
00752         role_.c_str(),
00753         factory_type.out ()
00754         ACE_ENV_ARG_PARAMETER);
00755   ACE_CHECK;
00756 
00757   CORBA::ULong factory_count = factories->length ();
00758   if (factory_count > 0)
00759     {
00760       CORBA::ULong factory_pos = 0;
00761       while (members_.current_size () < count && factory_pos < factory_count)
00762         {
00763           const PortableGroup::FactoryInfo & factory_info =
00764             (*factories)[factory_pos];
00765           const PortableGroup::Location & factory_location =
00766             factory_info.the_location;
00767           if (0 != this->members_.find (factory_location))
00768             {
00769               ///////////////////////////////////////////
00770               // If a factory refuses to create a replica
00771               // it's not fatal.
00772               ACE_TRY_NEW_ENV
00773                 {
00774                   PortableGroup::GenericFactory::FactoryCreationId_var fcid;
00775                   CORBA::Object_var member =
00776                     factory_info.the_factory->create_object (
00777                       this->type_id_.in (),
00778                       factory_info.the_criteria,
00779                       fcid. out()
00780                       ACE_ENV_ARG_PARAMETER);
00781                   ACE_TRY_CHECK;
00782 
00783                   // convert the new member to a stringified IOR to avoid
00784                   // contamination with group info
00785                   CORBA::String_var member_ior_string =
00786                     orb_->object_to_string (member.in ()
00787                                             ACE_ENV_ARG_PARAMETER);
00788                   ACE_TRY_CHECK;
00789 
00790                   PortableGroup::ObjectGroup_var new_reference =
00791                     this->add_member_to_iogr (member.in ()
00792                                               ACE_ENV_ARG_PARAMETER);
00793                   ACE_TRY_CHECK;
00794 
00795                   // Convert new member back to a (non group) ior.
00796                   CORBA::Object_var member_ior =
00797                     this->orb_->string_to_object (member_ior_string.in ()
00798                                                   ACE_ENV_ARG_PARAMETER);
00799                   ACE_TRY_CHECK;
00800 
00801                   MemberInfo * info = 0;
00802                   ACE_NEW_THROW_EX (info, MemberInfo(
00803                                                      member_ior.in(),
00804                                                      factory_location,
00805                                                      factory_info.the_factory,
00806                                                      fcid.in ()),
00807                                     CORBA::NO_MEMORY());
00808                   ACE_TRY_CHECK;
00809 
00810                   if (this->members_.bind (factory_location, info) != 0)
00811                     {
00812                       ACE_TRY_THROW(CORBA::NO_MEMORY());
00813                     }
00814                   this->reference_ =
00815                     new_reference; // note var-to-var assignment does
00816                                    // a duplicate
00817                 }
00818               ACE_CATCHANY
00819                 {
00820                   // log, but otherwise ignore the errorf
00821                   if (TAO_debug_level > 0)
00822                     {
00823                       ACE_ERROR ((LM_ERROR,
00824                                   ACE_TEXT ("PG (%P|%t) Replica Factory ")
00825                                   ACE_TEXT ("@ %s refused create_object ")
00826                                   ACE_TEXT ("request for type %s\n"),
00827                                   static_cast<const char *> (factory_info.the_location[0].id),
00828                                   static_cast<const char *> (this->type_id_.in ())
00829                                   ));
00830                     }
00831                 }
00832               ACE_ENDTRY;
00833             }
00834         }
00835 
00836       if (this->increment_version ())
00837         {
00838           this->distribute_iogr (ACE_ENV_SINGLE_ARG_PARAMETER);
00839           ACE_CHECK;
00840         }
00841     }
00842   else
00843     {
00844       ACE_THROW (PortableGroup::NoFactory());
00845     }
00846 }
00847 
00848 void
00849 TAO::PG_Object_Group::initial_populate (ACE_ENV_SINGLE_ARG_DECL)
00850 {
00851   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00852 
00853   if (this->get_membership_style () == PortableGroup::MEMB_INF_CTRL)
00854     {
00855       PortableGroup::InitialNumberMembersValue initial_number_members =
00856         this->get_initial_number_members ();
00857 
00858       if (this->members_.current_size () < initial_number_members)
00859         {
00860           this->create_members (initial_number_members
00861                                 ACE_ENV_ARG_PARAMETER);
00862           ACE_CHECK;
00863         }
00864     }
00865 }
00866 
00867 void
00868 TAO::PG_Object_Group::minimum_populate (ACE_ENV_SINGLE_ARG_DECL)
00869 {
00870   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00871 
00872   if ( this->get_membership_style () == PortableGroup::MEMB_INF_CTRL )
00873     {
00874       PortableGroup::MinimumNumberMembersValue minimum_number_members =
00875         this->get_minimum_number_members ();
00876       if (members_.current_size () < minimum_number_members)
00877         {
00878           this->create_members (minimum_number_members ACE_ENV_ARG_PARAMETER);
00879         }
00880     }
00881 }
00882 
00883 int
00884 TAO::PG_Object_Group::has_member_at (const PortableGroup::Location & location)
00885 {
00886   return (0 == this->members_.find (location));
00887 }
00888 
00889 TAO_END_VERSIONED_NAMESPACE_DECL
00890 
00891 // Restore original compiler flags.
00892 #if defined (__BORLANDC__) && (__BORLANDC__ <= 0x582)
00893 # pragma option pop
00894 # pragma nopushoptwarn
00895 # pragma nopackwarning
00896 #endif /* __BORLANDC__ && __BORLANDC__ <= 0x582 */

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