PG_Object_Group.cpp

Go to the documentation of this file.
00001 // $Id: PG_Object_Group.cpp 77001 2007-02-12 07:54:49Z johnnyw $
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 {
00155   // assume internals is locked
00156 
00157   PortableGroup::ObjectGroup_var result;
00158 
00159  ////////////////////////////
00160   // @@ HACK ALERT
00161   // The PortableGroup::ObjectGroupManager creates an object reference
00162   // containing a dummy entry so it will have a place to store the
00163   // tagged group component. If this is the first entry, we need to
00164   // remove that entry once we have a *real* member. This can be
00165   // avoided when we get support for TAG_MULTIPLE_COMPONENTS.   For
00166   // now, we already have a copy of the tagGroupTagged component and
00167   // we're going to use it below wen we increment the group version so
00168   // we can clean out the dummy entry.
00169   PortableGroup::ObjectGroup_var cleaned =
00170     PortableGroup::ObjectGroup::_duplicate (this->reference_.in ());
00171   if (this->empty_)
00172     {
00173       // remove the original profile.  It's a dummy entry supplied by
00174       // create_object.
00175       cleaned =
00176         this->manipulator_.remove_profiles (cleaned.in (),
00177                                             this->reference_.in ());
00178       this->empty_ = 0;
00179     }
00180 
00181   // create a list of references to be merged
00182   TAO_IOP::TAO_IOR_Manipulation::IORList iors (2);
00183   iors.length (2);
00184   iors [0] = CORBA::Object::_duplicate (cleaned.in());
00185   iors [1] = CORBA::Object::_duplicate (member);
00186 
00187   // Now merge the list into one new IOGR
00188   result =
00189     this->manipulator_.merge_iors (iors);
00190   return result._retn ();
00191 }
00192 
00193 void
00194 TAO::PG_Object_Group::add_member (const PortableGroup::Location & the_location,
00195                                   CORBA::Object_ptr member)
00196 
00197 {
00198   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00199 
00200   /////////////////////////////////////////
00201   // Convert the new member to a string IOR
00202   // This keeps a clean IOR (not an IOGR!)
00203   // while we add it to a group.  We need a
00204   // IORs, not IOGRs to send new IOGRs out
00205   // to replicas.
00206 
00207   CORBA::String_var member_ior_string =
00208     orb_->object_to_string (member);
00209 
00210   PortableGroup::ObjectGroup_var new_reference =
00211     add_member_to_iogr (member);
00212 
00213   // Convert new member back to a (non group) ior.
00214   CORBA::Object_var member_ior =
00215     this->orb_->string_to_object (member_ior_string.in ());
00216 
00217   MemberInfo * info = 0;
00218   ACE_NEW_THROW_EX (info,
00219                     MemberInfo (member_ior.in (),
00220                                 the_location),
00221                     CORBA::NO_MEMORY());
00222 
00223   if (this->members_.bind (the_location, info) != 0)
00224     {
00225       // @@ Dale why this is a NO MEMORY exception?
00226       throw CORBA::NO_MEMORY();
00227     }
00228 
00229   this->reference_ = new_reference; // note var-to-var assignment does
00230                                     // a duplicate
00231   if (this->increment_version ())
00232     {
00233       this->distribute_iogr ();
00234     }
00235   else
00236     {
00237       throw PortableGroup::ObjectNotAdded ();
00238     }
00239 
00240   if (TAO_debug_level > 6)
00241     {
00242       ACE_DEBUG ((LM_DEBUG,
00243                   ACE_TEXT("PG (%P|%t) exit Object_Group add_member \n")));
00244     }
00245 }
00246 
00247 int
00248 TAO::PG_Object_Group::set_primary_member (
00249     TAO_IOP::TAO_IOR_Property * prop,
00250     const PortableGroup::Location & the_location)
00251 {
00252   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00253                     guard,
00254                     this->internals_,
00255                     0);
00256   int result = 1;
00257   MemberInfo * info = 0;
00258   if (this->members_.find (the_location, info) == 0)
00259     {
00260       int cleared = 0;
00261       this->primary_location_ = the_location;
00262       for (MemberMap_Iterator it = this->members_.begin();
00263            !cleared && it != this->members_.end();
00264            ++it)
00265         {
00266           cleared = (*it).int_id_->is_primary_;
00267           (*it).int_id_->is_primary_ = 0;
00268         }
00269       info->is_primary_ = 1;
00270 
00271       int set_ok =
00272         this->manipulator_.set_primary (prop,
00273                                         this->reference_.in (),
00274                                         info->member_.in ());
00275       if (!set_ok)
00276         {
00277           if (TAO_debug_level > 3)
00278             {
00279               ACE_ERROR ((LM_ERROR,
00280                           ACE_TEXT ("%T %n (%P|%t) - ")
00281                           ACE_TEXT ("Can't set primary in IOGR .\n")
00282                           ));
00283             }
00284 //@@: ACE_THROW (FT::PrimaryNotSet());
00285           result = 0;
00286         }
00287 
00288       if (result && this->increment_version ())
00289         {
00290           this->distribute_iogr ();
00291         }
00292       else
00293         {
00294           if (TAO_debug_level > 3)
00295             {
00296               ACE_DEBUG ((LM_DEBUG,
00297                           ACE_TEXT("TAO-PG (%P|%t) - set_primary_location ")
00298                           ACE_TEXT("throwing PrimaryNotSet because increment")
00299                           ACE_TEXT("version failed.\n")
00300                           ));
00301             }
00302 //@@: ACE_THROW (FT::PrimaryNotSet());
00303           result = 0;
00304         }
00305     }
00306   else
00307     {
00308       if (TAO_debug_level > 3)
00309         {
00310           ACE_DEBUG ((LM_DEBUG,
00311                       ACE_TEXT ("TAO-PG (%P|%t) - set_primary_location ")
00312                       ACE_TEXT ("throwing MemberNotFound.\n")));
00313         }
00314       throw PortableGroup::MemberNotFound();
00315     }
00316 
00317   return result;
00318 }
00319 
00320 
00321 void
00322 TAO::PG_Object_Group::remove_member (
00323     const PortableGroup::Location & the_location)
00324 {
00325   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00326   MemberInfo * info = 0;
00327   if (this->members_.unbind (the_location, info) == 0)
00328     {
00329       if (this->members_.current_size() > 0)
00330         {
00331           this->reference_ =
00332             this->manipulator_.remove_profiles (this->reference_.in (),
00333                                                 info->member_.in ());
00334         }
00335       else
00336         {
00337           empty_ = 1;
00338         }
00339 
00340       delete info;
00341 
00342       if (the_location == this->primary_location_)
00343         {
00344           this->primary_location_.length(0);
00345         }
00346 
00347       if (this->increment_version ())
00348         {
00349           this->distribute_iogr ();
00350         }
00351 
00352     }
00353   else
00354     {
00355       if (TAO_debug_level > 6)
00356         {
00357           ACE_DEBUG ((LM_DEBUG,
00358                       "TAO-PG (%P|%t) - "
00359                       "remove_member throwing MemberNotFound.\n"
00360                       ));
00361         }
00362       throw PortableGroup::MemberNotFound();
00363     }
00364 }
00365 
00366 
00367 PortableGroup::ObjectGroupId
00368 TAO::PG_Object_Group::get_object_group_id (void) const
00369 {
00370   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00371                     guard,
00372                     this->internals_,
00373                     0);
00374   return this->tagged_component_.object_group_id;
00375 }
00376 
00377 void
00378 TAO::PG_Object_Group::set_properties_dynamically (
00379     const PortableGroup::Properties & overrides)
00380 {
00381   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00382 
00383   this->properties_.decode (overrides);
00384 
00385   //@@ int todo_override_rather_than_replace?
00386 }
00387 
00388 void
00389 TAO::PG_Object_Group::get_properties (
00390     PortableGroup::Properties_var & result) const
00391 {
00392   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00393   this->properties_.export_properties(*result);
00394 }
00395 
00396 
00397 PortableGroup::TypeId
00398 TAO::PG_Object_Group::get_type_id (void) const
00399 {
00400   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00401                     guard,
00402                     this->internals_,
00403                     0);
00404   return CORBA::string_dup (this->type_id_);
00405 }
00406 
00407 
00408 ///////////////////
00409 // Internal method
00410 
00411 int
00412 TAO::PG_Object_Group::increment_version (void)
00413 {
00414   // assume internals is locked
00415   int result = 0;
00416   this->tagged_component_.object_group_ref_version += 1;
00417   if (TAO_debug_level > 3)
00418     {
00419       ACE_DEBUG ((LM_DEBUG,
00420                   ACE_TEXT ("%T %n (%P|%t) - Setting IOGR version to %u\n"),
00421                   static_cast<unsigned> (this->tagged_component_.object_group_ref_version)
00422                   ));
00423     }
00424 
00425   // Set the version
00426   if (TAO::PG_Utils::set_tagged_component (this->reference_,
00427                                            this->tagged_component_))
00428     {
00429       result = 1;
00430     }
00431   return result;
00432 }
00433 
00434 
00435 //////////////////
00436 // Internal method
00437 void
00438 TAO::PG_Object_Group::distribute_iogr (void)
00439 {
00440   // assume internals is locked
00441   CORBA::String_var iogr =
00442     this->orb_->object_to_string (this->reference_.in());
00443 
00444 //  size_t n_rep = 0; // for dump_ior below
00445   for (MemberMap_Iterator it = this->members_.begin();
00446        it != this->members_.end ();
00447        ++it)
00448     {
00449       MemberInfo const * info = (*it).int_id_;
00450       //
00451       // Unchecked narrow means the member doesn't have to actually implement the TAO_UpdateObjectGroup interface
00452       // PortableGroup::TAO_UpdateObjectGroup_var uog = PortableGroup::TAO_UpdateObjectGroup::_unchecked_narrow ( info->member_);
00453       // but it doesn work: error message at replica is:
00454       // TAO-FT (2996|976) - Wrong version information within the interceptor [1 | 0]
00455       // TAO_Perfect_Hash_OpTable:find for operation 'tao_update_object_group' (length=23) failed
00456       // back to using _narrow
00457       PortableGroup::TAO_UpdateObjectGroup_var uog =
00458         PortableGroup::TAO_UpdateObjectGroup::_narrow ( info->member_.in ());
00459       if (!CORBA::is_nil (uog.in ()))
00460         {
00461           try
00462             {
00463               if (TAO_debug_level > 3)
00464                 {
00465                   ACE_DEBUG ((LM_DEBUG,
00466                               "PG (%P|%t) -  Object_Group pushing "
00467                               "IOGR to %s member: %s@%s.\n",
00468                               (info->is_primary_ ? "Primary" : "Backup"),
00469                               this->role_.c_str (),
00470                               static_cast<const char *> (info->location_[0].id)
00471                               ));
00472                 }
00473               //        dump_ior ("group", "iogr", this->tagged_component_.object_group_ref_version, iogr);
00474               //        CORBA::String_var replica_ior = this->orb_->object_to_string(uog.in());
00475               //        dump_ior (info->location_[0].id, "ior", (this->tagged_component_.object_group_ref_version * 100) + n_rep++, replica_ior);
00476               uog->tao_update_object_group (iogr.in (),
00477                                             this->tagged_component_.object_group_ref_version,
00478                                             info->is_primary_);
00479             }
00480           catch (const CORBA::Exception&)
00481             {
00482               // we expect an exception
00483               // tao_update_object_group is not a real method
00484             }
00485         }
00486       else
00487         {
00488           ACE_ERROR ((LM_ERROR,
00489                       "TAO::PG_Object_Group::distribute iogr can't "
00490                       "narrow member reference to "
00491                       "PortableGroup::TAO_UpdateObjectGroup.\n"
00492                       ));
00493         }
00494     }
00495 }
00496 
00497 PortableGroup::Locations *
00498 TAO::PG_Object_Group::locations_of_members (void)
00499 {
00500   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00501                     guard,
00502                     this->internals_,
00503                     0);
00504 
00505   PortableGroup::Locations * result = 0;
00506 
00507   size_t count = this->members_.current_size ();
00508 
00509   ACE_NEW_THROW_EX (
00510     result,
00511     PortableGroup::Locations (count),
00512     CORBA::NO_MEMORY() );
00513 
00514   result->length (count);
00515 
00516   size_t pos = 0;
00517   for (MemberMap_Iterator it = this->members_.begin();
00518       it != this->members_.end();
00519       ++it)
00520   {
00521     const PortableGroup::Location & location = (*it).ext_id_;
00522     PortableGroup::Location & out = (*result)[pos];
00523     out = location;
00524   }
00525   return result;
00526 }
00527 
00528 CORBA::Object_ptr
00529 TAO::PG_Object_Group::get_member_reference (
00530     const PortableGroup::Location & the_location)
00531 {
00532   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00533                     guard,
00534                     this->internals_,
00535                     CORBA::Object::_nil ());
00536 
00537   CORBA::Object_var result;
00538 
00539   MemberInfo * info = 0;
00540   if (this->members_.find (the_location, info) == 0)
00541     {
00542       result = CORBA::Object::_duplicate (info->member_.in ());
00543     }
00544   else
00545     {
00546       throw PortableGroup::MemberNotFound();
00547     }
00548   return result._retn ();
00549 }
00550 
00551 
00552 PortableGroup::MembershipStyleValue
00553 TAO::PG_Object_Group::get_membership_style (void) const
00554 {
00555   PortableGroup::MembershipStyleValue membership_style = 0;
00556   if (!TAO::find (properties_,
00557                   PortableGroup::PG_MEMBERSHIP_STYLE,
00558                   membership_style))
00559     {
00560       membership_style = TAO_PG_MEMBERSHIP_STYLE;
00561     }
00562   return membership_style;
00563 }
00564 
00565 
00566 PortableGroup::MinimumNumberMembersValue
00567 TAO::PG_Object_Group::get_minimum_number_members (void) const
00568 {
00569   PortableGroup::MinimumNumberMembersValue minimum_number_members = 0;
00570   if (!TAO::find (properties_,
00571                   PortableGroup::PG_MINIMUM_NUMBER_MEMBERS,
00572                   minimum_number_members))
00573     {
00574       minimum_number_members = TAO_PG_MINIMUM_NUMBER_MEMBERS;
00575     }
00576   return minimum_number_members;
00577 }
00578 
00579 PortableGroup::InitialNumberMembersValue
00580 TAO::PG_Object_Group::get_initial_number_members (void) const
00581 {
00582   PortableGroup::InitialNumberMembersValue initial_number_members = 0;
00583   if (!TAO::find (properties_,
00584                   PortableGroup::PG_INITIAL_NUMBER_MEMBERS,
00585                   initial_number_members))
00586     {
00587       initial_number_members = TAO_PG_INITIAL_NUMBER_MEMBERS;
00588     }
00589   return initial_number_members;
00590 }
00591 
00592 void
00593 TAO::PG_Object_Group::create_member (
00594     const PortableGroup::Location & the_location,
00595     const char * type_id,
00596     const PortableGroup::Criteria & the_criteria)
00597 {
00598   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00599 
00600 
00601   if (0 != this->members_.find (the_location))
00602     {
00603       // @@ what if factories were passed as criteria?
00604 
00605       CORBA::String_var factory_type;
00606       PortableGroup::FactoryInfos_var factories =
00607         this->factory_registry_->list_factories_by_role (
00608           role_.c_str(),
00609           factory_type.out ());
00610 
00611       // @@ what if factory_type != type_id != this->type_id_
00612 
00613       int created = 0; // bool
00614       CORBA::ULong factory_count = factories->length ();
00615       for (CORBA::ULong factory_pos = 0;
00616            ! created && factory_pos < factory_count;
00617            ++factory_pos)
00618         {
00619           const PortableGroup::FactoryInfo & factory_info =
00620             (*factories)[factory_pos];
00621           if (factory_info.the_location == the_location)
00622             {
00623               // @@ should we merge the_criteria with
00624               // factory_info.the_criteria?
00625 
00626               PortableGroup::GenericFactory::FactoryCreationId_var fcid;
00627               CORBA::Object_var member =
00628                 factory_info.the_factory->create_object (
00629                   type_id,
00630                   the_criteria,
00631                   fcid. out());
00632 
00633               // convert the new member to a stringified IOR to avoid
00634               // contamination with group info
00635               CORBA::String_var member_ior_string =
00636                 orb_->object_to_string (member.in ());
00637 
00638               PortableGroup::ObjectGroup_var new_reference =
00639                 this->add_member_to_iogr (member.in ());
00640 
00641               // Convert new member back to a (non group) ior.
00642               CORBA::Object_var member_ior =
00643                 this->orb_->string_to_object (member_ior_string.in ());
00644 
00645               MemberInfo * info = 0;
00646               ACE_NEW_THROW_EX (info, MemberInfo(
00647                                                  member_ior.in(),
00648                                                  the_location,
00649                                                  factory_info.the_factory,
00650                                                  fcid.in ()),
00651                                 CORBA::NO_MEMORY());
00652 
00653               if (this->members_.bind (the_location, info) != 0)
00654                 {
00655                   throw CORBA::NO_MEMORY();
00656                 }
00657 
00658               this->reference_ = new_reference; // note var-to-var
00659                                                 // assignment does a
00660                                                 // duplicate
00661               if (this->increment_version ())
00662                 {
00663                   this->distribute_iogr ();
00664                 }
00665               created = 1;
00666             }
00667         }
00668       if (! created)
00669         {
00670           throw PortableGroup::NoFactory ();
00671         }
00672     }
00673   else
00674     {
00675       throw PortableGroup::MemberAlreadyPresent ();
00676     }
00677 }
00678 
00679 void
00680 TAO::PG_Object_Group::create_members (size_t count)
00681 {
00682   // assume internals is locked
00683   // @@ what if factories were passed as criteria?
00684 
00685   CORBA::String_var factory_type;
00686   PortableGroup::FactoryInfos_var factories =
00687   this->factory_registry_->list_factories_by_role (
00688         role_.c_str(),
00689         factory_type.out ());
00690 
00691   CORBA::ULong factory_count = factories->length ();
00692   if (factory_count > 0)
00693     {
00694       CORBA::ULong factory_pos = 0;
00695       while (members_.current_size () < count && factory_pos < factory_count)
00696         {
00697           const PortableGroup::FactoryInfo & factory_info =
00698             (*factories)[factory_pos];
00699           const PortableGroup::Location & factory_location =
00700             factory_info.the_location;
00701           if (0 != this->members_.find (factory_location))
00702             {
00703               ///////////////////////////////////////////
00704               // If a factory refuses to create a replica
00705               // it's not fatal.
00706               try
00707                 {
00708                   PortableGroup::GenericFactory::FactoryCreationId_var fcid;
00709                   CORBA::Object_var member =
00710                     factory_info.the_factory->create_object (
00711                       this->type_id_.in (),
00712                       factory_info.the_criteria,
00713                       fcid. out());
00714 
00715                   // convert the new member to a stringified IOR to avoid
00716                   // contamination with group info
00717                   CORBA::String_var member_ior_string =
00718                     orb_->object_to_string (member.in ());
00719 
00720                   PortableGroup::ObjectGroup_var new_reference =
00721                     this->add_member_to_iogr (member.in ());
00722 
00723                   // Convert new member back to a (non group) ior.
00724                   CORBA::Object_var member_ior =
00725                     this->orb_->string_to_object (member_ior_string.in ());
00726 
00727                   MemberInfo * info = 0;
00728                   ACE_NEW_THROW_EX (info, MemberInfo(
00729                                                      member_ior.in(),
00730                                                      factory_location,
00731                                                      factory_info.the_factory,
00732                                                      fcid.in ()),
00733                                     CORBA::NO_MEMORY());
00734 
00735                   if (this->members_.bind (factory_location, info) != 0)
00736                     {
00737                       throw CORBA::NO_MEMORY();
00738                     }
00739                   this->reference_ =
00740                     new_reference; // note var-to-var assignment does
00741                                    // a duplicate
00742                 }
00743               catch (const CORBA::Exception&)
00744                 {
00745                   // log, but otherwise ignore the errorf
00746                   if (TAO_debug_level > 0)
00747                     {
00748                       ACE_ERROR ((LM_ERROR,
00749                                   ACE_TEXT ("PG (%P|%t) Replica Factory ")
00750                                   ACE_TEXT ("@ %s refused create_object ")
00751                                   ACE_TEXT ("request for type %s\n"),
00752                                   static_cast<const char *> (factory_info.the_location[0].id),
00753                                   static_cast<const char *> (this->type_id_.in ())
00754                                   ));
00755                     }
00756                 }
00757             }
00758         }
00759 
00760       if (this->increment_version ())
00761         {
00762           this->distribute_iogr ();
00763         }
00764     }
00765   else
00766     {
00767       throw PortableGroup::NoFactory();
00768     }
00769 }
00770 
00771 void
00772 TAO::PG_Object_Group::initial_populate (void)
00773 {
00774   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00775 
00776   if (this->get_membership_style () == PortableGroup::MEMB_INF_CTRL)
00777     {
00778       PortableGroup::InitialNumberMembersValue initial_number_members =
00779         this->get_initial_number_members ();
00780 
00781       if (this->members_.current_size () < initial_number_members)
00782         {
00783           this->create_members (initial_number_members);
00784         }
00785     }
00786 }
00787 
00788 void
00789 TAO::PG_Object_Group::minimum_populate (void)
00790 {
00791   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00792 
00793   if ( this->get_membership_style () == PortableGroup::MEMB_INF_CTRL )
00794     {
00795       PortableGroup::MinimumNumberMembersValue minimum_number_members =
00796         this->get_minimum_number_members ();
00797       if (members_.current_size () < minimum_number_members)
00798         {
00799           this->create_members (minimum_number_members);
00800         }
00801     }
00802 }
00803 
00804 int
00805 TAO::PG_Object_Group::has_member_at (const PortableGroup::Location & location)
00806 {
00807   return (0 == this->members_.find (location));
00808 }
00809 
00810 TAO_END_VERSIONED_NAMESPACE_DECL
00811 
00812 // Restore original compiler flags.
00813 #if defined (__BORLANDC__) && (__BORLANDC__ <= 0x582)
00814 # pragma option pop
00815 # pragma nopushoptwarn
00816 # pragma nopackwarning
00817 #endif /* __BORLANDC__ && __BORLANDC__ <= 0x582 */

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