TAO_PG_GenericFactory Class Reference

PortableGroup::GenericFactory implementation used by the load balancer when creating object groups. More...

#include <PG_GenericFactory.h>

Inheritance diagram for TAO_PG_GenericFactory:

Inheritance graph
[legend]
Collaboration diagram for TAO_PG_GenericFactory:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 TAO_PG_GenericFactory (TAO_PG_ObjectGroupManager &object_group_map, TAO_PG_PropertyManager &property_manager)
 Constructor.
 ~TAO_PG_GenericFactory (void)
 Destructor.
void poa (PortableServer::POA_ptr p)
 Set the POA to use when creating object references.
void delete_object_i (TAO_PG_Factory_Set &factory_set, CORBA::Boolean ignore_exceptions)
void delete_member (CORBA::ULong group_id, const PortableGroup::Location &location)
void check_minimum_number_members (PortableGroup::ObjectGroup_ptr object_group, CORBA::ULong group_id, const char *type_id)
 Verify that the MinimumNumberMembers criterion is satisfied.
PortableGroup::GenericFactory::FactoryCreationIdcreate_member (PortableGroup::ObjectGroup_ptr object_group, const PortableGroup::FactoryInfo &factory_info, const char *type_id, const CORBA::Boolean propagate_member_already_present)
TAO_LoadBalancer::GenericFactory methods
virtual CORBA::Object_ptr create_object (const char *type_id, const PortableGroup::Criteria &the_criteria, PortableGroup::GenericFactory::FactoryCreationId_out factory_creation_id)
virtual void delete_object (const PortableGroup::GenericFactory::FactoryCreationId &factory_creation_id)

Private Member Functions

void populate_object_group (PortableGroup::ObjectGroup_ptr object_group, const char *type_id, const PortableGroup::FactoryInfos &factory_infos, PortableGroup::InitialNumberMembersValue initial_number_members, TAO_PG_Factory_Set &factory_set)
void get_ObjectId (CORBA::ULong fcid, PortableServer::ObjectId_out oid)
 Get a new ObjectId to be used when creating a new ObjectGroup.
void process_criteria (const char *type_id, const PortableGroup::Criteria &criteria, PortableGroup::MembershipStyleValue &membership_style, PortableGroup::FactoriesValue &factory_infos, PortableGroup::InitialNumberMembersValue &initial_number_members, PortableGroup::MinimumNumberMembersValue &minimum_number_members)

Private Attributes

PortableServer::POA_var poa_
 Reference to the POA used to create object group references.
TAO_PG_ObjectGroupManagerobject_group_manager_
 Reference to the ObjectGroup map.
TAO_PG_PropertyManagerproperty_manager_
 Reference to the PropertyManager.
TAO_PG_Factory_Map factory_map_
 Table that maps FactoryCreationId to TAO_PG_Factory_Set.
CORBA::ULong next_fcid_
TAO_SYNCH_MUTEX lock_

Detailed Description

PortableGroup::GenericFactory implementation used by the load balancer when creating object groups.

This GenericFactory creates an object group reference for given set of replicas. Those replicas will be created by this GenericFactory if the "infrastructure-controlled" membership style is configured.

Definition at line 50 of file PG_GenericFactory.h.


Constructor & Destructor Documentation

TAO_BEGIN_VERSIONED_NAMESPACE_DECL TAO_PG_GenericFactory::TAO_PG_GenericFactory ( TAO_PG_ObjectGroupManager object_group_map,
TAO_PG_PropertyManager property_manager 
)

Constructor.

Definition at line 19 of file PG_GenericFactory.cpp.

00022   : poa_ (),
00023     object_group_manager_ (object_group_manager),
00024     property_manager_ (property_manager),
00025     factory_map_ (TAO_PG_MAX_OBJECT_GROUPS),
00026     next_fcid_ (0),
00027     lock_ ()
00028 {
00029   this->object_group_manager_.generic_factory (this);
00030 }

TAO_PG_GenericFactory::~TAO_PG_GenericFactory ( void   ) 

Destructor.

Definition at line 32 of file PG_GenericFactory.cpp.

References factory_map_.

00033 {
00034 
00035   TAO_PG_Factory_Map::iterator end = this->factory_map_.end ();
00036   for (TAO_PG_Factory_Map::iterator i = this->factory_map_.begin ();
00037        i != end;
00038        ++i)
00039     {
00040       TAO_PG_Factory_Set & factory_set = (*i).int_id_;
00041 
00042       try
00043         {
00044           this->delete_object_i (factory_set,
00045                                  1 /* Ignore exceptions */);
00046         }
00047       catch (const CORBA::Exception&)
00048         {
00049           // Ignore all exceptions.
00050         }
00051     }
00052 
00053   (void) this->factory_map_.close ();
00054 }


Member Function Documentation

void TAO_PG_GenericFactory::check_minimum_number_members ( PortableGroup::ObjectGroup_ptr  object_group,
CORBA::ULong  group_id,
const char *  type_id 
)

Verify that the MinimumNumberMembers criterion is satisfied.

If the current number of members in the given object group is less than the MinimumNumberMembers criterion in effect for that group, the infrastructure will attempt create and add more members to the group by invoking any unused application-supplied GenericFactorys.

Definition at line 546 of file PG_GenericFactory.cpp.

References create_member(), TAO_PG_PropertyManager::get_properties(), TAO_PG::get_property_value(), TAO_PG_ObjectGroupManager::member_count(), object_group_manager_, property_manager_, ACE_Array_Base< T >::size(), and CORBA::string_dup().

Referenced by TAO_PG_ObjectGroupManager::remove_member().

00550 {
00551   // Check if we've dropped below the MinimumNumberMembers threshold.
00552   // If so, attempt to create enough new members to fill the gap.
00553 
00554   // If no entry exists in the factory map, infrastructure (this
00555   // GenericFactory implementation) controlled membership was not
00556   // used.
00557   TAO_PG_Factory_Map::ENTRY *entry = 0;
00558   if (this->factory_map_.find (group_id, entry) != 0)
00559     return;
00560 
00561   TAO_PG_Factory_Set & factory_set = entry->int_id_;
00562 
00563   PortableGroup::Properties_var props =
00564     this->property_manager_.get_properties (object_group);
00565 
00566   PortableGroup::Name name (1);
00567   name.length (1);
00568 
00569   PortableGroup::Value value;
00570 
00571   // MinimumNumberMembers
00572   name[0].id =
00573     CORBA::string_dup ("org.omg.PortableGroup.MinimumNumberMembers");
00574 
00575   PortableGroup::MinimumNumberMembersValue minimum_number_members;
00576 
00577   if (TAO_PG::get_property_value (name, props.in (), value))
00578     {
00579       if (!(value >>= minimum_number_members))
00580         {
00581           // This only occurs if extraction of the actual value from
00582           // the Any fails.  It shouldn't fail at this point.
00583           throw CORBA::INTERNAL ();
00584         }
00585 
00586       const CORBA::ULong count =
00587         this->object_group_manager_.member_count (object_group);
00588 
00589       if (count >= static_cast<CORBA::ULong> (minimum_number_members))
00590         return;
00591 
00592       const CORBA::ULong gap =
00593         static_cast<CORBA::ULong> (minimum_number_members) - count;
00594 
00595       CORBA::ULong creation_count = 0;
00596 
00597       const size_t len = factory_set.size ();
00598 
00599       static const PortableGroup::GenericFactory::FactoryCreationId *
00600         nil_fcid = 0;
00601 
00602       for (size_t i = 0; i < len; ++i)
00603         {
00604           TAO_PG_Factory_Node & node = factory_set[i];
00605 
00606           PortableGroup::GenericFactory::FactoryCreationId * const tmp_fcid =
00607             node.factory_creation_id;
00608 
00609           // Check if the application supplied GenericFactory was
00610           // already invoked.
00611           if (tmp_fcid != nil_fcid)
00612             continue;
00613 
00614           try
00615             {
00616               const CORBA::Boolean propagate_member_already_present = 1;
00617 
00618               node.factory_creation_id =
00619                 this->create_member (object_group,
00620                                      node.factory_info,
00621                                      type_id,
00622                                      propagate_member_already_present);
00623 
00624               ++creation_count;
00625 
00626               // Check if the MinimumNumberMembers threshold gap has
00627               // been filled.
00628               if (gap == creation_count)
00629                 return;
00630             }
00631           catch (const PortableGroup::MemberAlreadyPresent&)
00632             {
00633               // Ignore this exception and continue.
00634             }
00635         }
00636 
00637       // @todo If we get this far, and the MinimumNumberMembers
00638       //       threshold gap hasn't been filled, what do we do?  Throw
00639       //       a CORBA::TRANSIENT?
00640     }
00641 }

PortableGroup::GenericFactory::FactoryCreationId * TAO_PG_GenericFactory::create_member ( PortableGroup::ObjectGroup_ptr  object_group,
const PortableGroup::FactoryInfo factory_info,
const char *  type_id,
const CORBA::Boolean  propagate_member_already_present 
)

Note:
This method is only used by the infrastructure.

Definition at line 644 of file PG_GenericFactory.cpp.

References TAO_PG_ObjectGroupManager::_tao_add_member(), TAO_Pseudo_Var_T< T >::in(), CORBA::is_nil(), object_group_manager_, PortableGroup::FactoryInfo::the_criteria, PortableGroup::FactoryInfo::the_factory, and PortableGroup::FactoryInfo::the_location.

Referenced by check_minimum_number_members(), and populate_object_group().

00649 {
00650   PortableGroup::GenericFactory::FactoryCreationId_var fcid;
00651 
00652   CORBA::Object_var member =
00653     factory_info.the_factory->create_object (type_id,
00654                                              factory_info.the_criteria,
00655                                              fcid.out ());
00656 
00657   try
00658     {
00659       // @@ Should an "_is_a()" be performed here?  While it
00660       //    appears to be the right thing to do, it can be
00661       //    expensive.
00662       //
00663       // Make sure an Object of the correct type was created.
00664       // It is possible that an object of the wrong type was
00665       // created if the type_id parameter does not match the
00666       // type of object the GenericFactory creates.
00667       CORBA::Boolean right_type_id =
00668         member->_is_a (type_id);
00669 
00670       // @todo Strategize this -- e.g. strict type checking.
00671       if (!right_type_id)
00672         {
00673           // An Object of incorrect type was created.  Delete
00674           // it, and throw a NoFactory exception.
00675           factory_info.the_factory->delete_object (fcid.in ());
00676 
00677           throw PortableGroup::NoFactory (factory_info.the_location, type_id);
00678         }
00679 
00680       this->object_group_manager_._tao_add_member (
00681         object_group,
00682         factory_info.the_location,
00683         member.in (),
00684         type_id,
00685         propagate_member_already_present);
00686     }
00687   catch (const CORBA::Exception&)
00688     {
00689       // If the member reference is not nil, then the factory
00690       // was successfully invoked.  Since an exception was
00691       // thrown, clean up the up created member.
00692       if (!CORBA::is_nil (member.in ()))
00693         {
00694           factory_info.the_factory->delete_object (fcid.in ());
00695         }
00696 
00697       throw;
00698     }
00699 
00700   return fcid._retn ();
00701 }

CORBA::Object_ptr TAO_PG_GenericFactory::create_object ( const char *  type_id,
const PortableGroup::Criteria the_criteria,
PortableGroup::GenericFactory::FactoryCreationId_out  factory_creation_id 
) [virtual]

Create an object of the specified type that adheres to the restrictions defined by the provided Criteria. The out FactoryCreationId parameter may be passed to the delete_object() method to delete the object.

Definition at line 57 of file PG_GenericFactory.cpp.

References CORBA::Object::_nil(), CORBA::SystemException::_tao_minor_code(), ACE_GUARD_RETURN, ACE_NEW_THROW_EX, CORBA::COMPLETED_NO, TAO_PG_ObjectGroupManager::create_object_group(), delete_object_i(), TAO_PG_ObjectGroupManager::destroy_object_group(), get_ObjectId(), TAO_PG_PropertyManager::get_type_properties(), PortableGroup::MEMB_INF_CTRL, next_fcid_, object_group_manager_, populate_object_group(), process_criteria(), property_manager_, TAO_PG_INITIAL_NUMBER_MEMBERS, TAO_PG_MEMBERSHIP_STYLE, TAO_PG_MINIMUM_NUMBER_MEMBERS, TAO_SYNCH_MUTEX, and TAO::VMCID.

00061 {
00062   PortableGroup::Properties_var properties =
00063     this->property_manager_.get_type_properties (type_id);
00064 
00065   PortableGroup::MembershipStyleValue membership_style =
00066     TAO_PG_MEMBERSHIP_STYLE;
00067   PortableGroup::FactoriesValue factory_infos(0);
00068 
00069   PortableGroup::InitialNumberMembersValue initial_number_members =
00070     TAO_PG_INITIAL_NUMBER_MEMBERS;
00071   PortableGroup::MinimumNumberMembersValue minimum_number_members =
00072     TAO_PG_MINIMUM_NUMBER_MEMBERS;
00073 
00074   // Make sure the criteria for the object group being created are
00075   // valid.
00076   this->process_criteria (type_id,
00077                           the_criteria,
00078                           membership_style,
00079                           factory_infos,
00080                           initial_number_members,
00081                           minimum_number_members);
00082 
00083   CORBA::ULong fcid = 0;
00084 
00085   {
00086     ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00087                       guard,
00088                       this->lock_,
00089                       CORBA::Object::_nil ());
00090 
00091     // Start out with an initial value.
00092     fcid = this->next_fcid_;
00093 
00094     // Loop until a free FactoryCreationId is found, being careful to
00095     // search through the range of FactoryCreationIds only once.
00096     while (this->factory_map_.find (this->next_fcid_) == 0)
00097       {
00098         this->next_fcid_++;
00099 
00100         // If this is true, then no FactoryCreationIds are available.
00101         // This is highly unlikely since TAO implements a
00102         // FactoryCreationId as a 32 bit unsigned integer, meaning
00103         // that over 4 billion object groups are being managed by this
00104         // generic factory!
00105         if (this->next_fcid_ == fcid)
00106           throw PortableGroup::ObjectNotCreated ();
00107       }
00108 
00109     // Just in case this->next_fcid_ was modified in the above search,
00110     // reassign the value.
00111     fcid = this->next_fcid_;
00112   }
00113 
00114   // The ObjectId for the newly created object group is comprised
00115   // solely of the FactoryCreationId.
00116   PortableServer::ObjectId_var oid;
00117   this->get_ObjectId (fcid, oid.out ());
00118 
00119   PortableGroup::ObjectGroup_var object_group =
00120     this->object_group_manager_.create_object_group (fcid,
00121                                                      oid.in (),
00122                                                      type_id,
00123                                                      the_criteria);
00124 
00125   TAO_PG_Factory_Set factory_set;
00126 
00127   const CORBA::ULong factory_infos_count = factory_infos.length ();
00128 
00129   try
00130     {
00131       if (factory_infos_count > 0
00132           && membership_style == PortableGroup::MEMB_INF_CTRL)
00133         {
00134           this->populate_object_group (object_group.in (),
00135                                        type_id,
00136                                        factory_infos,
00137                                        initial_number_members,
00138                                        factory_set);
00139 
00140           if (this->factory_map_.bind (fcid, factory_set) != 0)
00141             throw PortableGroup::ObjectNotCreated ();
00142 
00143         }
00144 
00145       // Allocate a new FactoryCreationId for use as an "out" parameter.
00146       PortableGroup::GenericFactory::FactoryCreationId * tmp = 0;
00147       ACE_NEW_THROW_EX (tmp,
00148                         PortableGroup::GenericFactory::FactoryCreationId,
00149                         CORBA::NO_MEMORY (
00150                           CORBA::SystemException::_tao_minor_code (
00151                             TAO::VMCID,
00152                             ENOMEM),
00153                           CORBA::COMPLETED_NO));
00154 
00155       factory_creation_id = tmp;
00156 
00157       *tmp <<= fcid;
00158     }
00159   catch (const CORBA::Exception&)
00160     {
00161       this->delete_object_i (factory_set,
00162                              1 /* Ignore exceptions */);
00163 
00164       this->object_group_manager_.destroy_object_group (oid.in ());
00165 
00166       throw;
00167     }
00168 
00169   {
00170     ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00171                       guard,
00172                       this->lock_,
00173                       CORBA::Object::_nil ());
00174 
00175     // Object group was successfully created.  Increment the next
00176     // FactoryCreationId in preparation for the next object group.
00177     this->next_fcid_++;
00178   }
00179 
00180   return object_group._retn ();
00181 }

void TAO_PG_GenericFactory::delete_member ( CORBA::ULong  group_id,
const PortableGroup::Location location 
)

This method is only used by the TAO_PG_ObjectGroupManager class when ObjectGroupManager::remove_member() is explicitly called.

Definition at line 273 of file PG_GenericFactory.cpp.

References ACE_GUARD, TAO_SYNCH_MUTEX, PortableGroup::FactoryInfo::the_factory, and PortableGroup::FactoryInfo::the_location.

Referenced by TAO_PG_ObjectGroupManager::remove_member().

00276 {
00277   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00278 
00279   // If no entry exists in the factory map, infrastructure
00280   // controlled membership was not used.
00281   TAO_PG_Factory_Map::ENTRY *entry = 0;
00282   if (this->factory_map_.find (group_id, entry) == 0)
00283     {
00284       TAO_PG_Factory_Set & factory_set = entry->int_id_;
00285 
00286       const size_t len = factory_set.size ();
00287 
00288       // Iterate through the factory_set until a location match
00289       // occurs.  If a location match occurs, the member was created
00290       // by the infrastructure, i.e. this GenericFactory
00291       // implementation.  If no location matches, the member was
00292       // created by the application, and no operation will be
00293       // performed.
00294       //
00295       // @todo This is linear search.  Change to use a container with
00296       //       better search times.
00297       for (size_t i = 0; i < len; ++i)
00298         {
00299           TAO_PG_Factory_Node & node = factory_set[i];
00300           PortableGroup::FactoryInfo & info = node.factory_info;
00301 
00302           if (info.the_location == location)
00303             {
00304               info.the_factory->delete_object (node.factory_creation_id.in ());
00305 
00306               // The member has been successfully deleted.  Reduce the
00307               // size of the factory_set accordingly.
00308               if (len > 1)
00309                 {
00310                   // Move the last element to the location of the
00311                   // current one and reduce the size of the set by
00312                   // one.
00313                   const size_t new_len = len - 1;
00314                   node = factory_set[new_len]; // Memberwise copy
00315                   factory_set.size (new_len);
00316                 }
00317               else
00318                 {
00319                   // A copy isn't necessary if the last member was
00320                   // deleted.
00321                   factory_set.size (0);
00322                 }
00323 
00324               return;
00325             }
00326         }
00327     }
00328 }

void TAO_PG_GenericFactory::delete_object ( const PortableGroup::GenericFactory::FactoryCreationId factory_creation_id  )  [virtual]

Delete the object corresponding to the provided FactoryCreationId. If the object is actually an ObjectGroup, then all members within the ObjectGroup will be deleted. Afterward, the ObjectGroup itself will be deleted.

Definition at line 184 of file PG_GenericFactory.cpp.

References ACE_GUARD, TAO_PG_ObjectGroupManager::destroy_object_group(), get_ObjectId(), object_group_manager_, and TAO_SYNCH_MUTEX.

00187 {
00188   CORBA::ULong fcid = 0;
00189 
00190   if (factory_creation_id >>= fcid) // Extract the actual FactoryCreationId.
00191     {
00192       // Successfully extracted the FactoryCreationId.  Now find the
00193       // TAO_PG_Factory_Set corresponding to it.
00194 
00195       ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00196 
00197       // If no entry exists in the factory map, infrastructure
00198       // controlled membership was not used.
00199       TAO_PG_Factory_Map::ENTRY *entry = 0;
00200       if (this->factory_map_.find (fcid, entry) == 0)
00201         {
00202           TAO_PG_Factory_Set & factory_set = entry->int_id_;
00203 
00204           this->delete_object_i (factory_set,
00205                                  0  /* Do not ignore exceptions */);
00206 
00207           if (this->factory_map_.unbind (fcid) != 0)
00208             throw CORBA::INTERNAL ();
00209         }
00210     }
00211   else
00212     throw PortableGroup::ObjectNotFound ();  // @@
00213                                                    //    CORBA::BAD_PARAM
00214                                                    //    instead?
00215 
00216   // The ObjectId for the newly created object group is comprised
00217   // solely of the FactoryCreationId.
00218   PortableServer::ObjectId_var oid;
00219   this->get_ObjectId (fcid, oid.out ());
00220 
00221   // Destroy the object group entry.
00222   this->object_group_manager_.destroy_object_group (
00223     oid.in ());
00224 }

void TAO_PG_GenericFactory::delete_object_i ( TAO_PG_Factory_Set factory_set,
CORBA::Boolean  ignore_exceptions 
)

If ignore_exceptions is true, any exception returned from the delete_object() call on the remote factory will be ignored in order to allow other objects to be deleted via other registered factories.

Definition at line 227 of file PG_GenericFactory.cpp.

References TAO_PG_Factory_Node::factory_creation_id, TAO_PG_Factory_Node::factory_info, ACE_Array_Base< T >::size(), and PortableGroup::FactoryInfo::the_factory.

Referenced by create_object(), and TAO_PG_Group_Guard::~TAO_PG_Group_Guard().

00229 {
00230   const size_t len = factory_set.size ();
00231 
00232   size_t ilen = len;
00233   for (size_t i = 0; i != len; ++i)
00234     {
00235       // Destroy the object group member in reverse order in case the
00236       // array list is only partially destroyed and another call to
00237       // GenericFactory::delete_object() occurs afterwards.
00238       --ilen;
00239 
00240       TAO_PG_Factory_Node & factory_node = factory_set[ilen];
00241 
00242       PortableGroup::GenericFactory_ptr factory =
00243         factory_node.factory_info.the_factory.in ();
00244       const PortableGroup::GenericFactory::FactoryCreationId & member_fcid =
00245         factory_node.factory_creation_id.in ();
00246 
00247       try
00248         {
00249           factory->delete_object (member_fcid);
00250         }
00251       catch (const CORBA::Exception&)
00252         {
00253           // Exceptions are generally only ignored when this
00254           // GenericFactory (not the one being invoked above) is
00255           // destroyed.  The idea is to allow the GenericFactory to be
00256           // destroyed regardless of whether or not all object group
00257           // members have been destroyed, and minimize the number of
00258           // object group members that have not been destroyed.
00259           if (!ignore_exceptions)
00260             throw;
00261         }
00262 
00263       // Since GenericFactory::delete_object() can throw an exception,
00264       // decrease the size of the factory array incrementally since
00265       // some object group members may not have been destroyed yet.
00266       // Note that this size reduction is fast since no memory is
00267       // actually deallocated.
00268       factory_set.size (ilen);
00269     }
00270 }

void TAO_PG_GenericFactory::get_ObjectId ( CORBA::ULong  fcid,
PortableServer::ObjectId_out  oid 
) [private]

Get a new ObjectId to be used when creating a new ObjectGroup.

An ObjectId created by this method will never be reused within the scope of a given ReplicationManager. A value suitable for use in a map association <ext_id> is also returned.

Definition at line 385 of file PG_GenericFactory.cpp.

References ACE_OS::sprintf(), and PortableServer::string_to_ObjectId().

Referenced by create_object(), and delete_object().

00388 {
00389   // Since the POA used by the LoadManager uses the NON_RETAIN
00390   // policy, explicitly choose an ObjectId that is unique to a given
00391   // type.
00392 
00393   // Make the ObjectId be the next value of the number of types that
00394   // have been registered with the LoadManager.  For example, if two
00395   // types of objects have been registered with the LoadManager, then
00396   // the ObjectId for the object currently being registered will be
00397   // "3" since the object will be the third type of object registered
00398   // with the LoadManager.  Previously used values will not be reused
00399   // to ensure that a ServantLocator does not inadvertently return a
00400   // reference to an object that had a previously used ObjectId.
00401   // Specifcally, the numerical value used for the ObjectId increases
00402   // monotonically.
00403 
00404   // 4294967295UL -- Largest 32 bit unsigned integer
00405   // 123456789012 -- 10 digits
00406   //                + 2 for "UL"  (unnecessary, but let's be safe)
00407   //                + 1 for null terminator
00408   //                + 1 for good luck. :-)
00409   const size_t MAX_OID_LEN = 14;
00410 
00411   char oid_str[MAX_OID_LEN] = { 0 };
00412   ACE_OS::sprintf (oid_str,
00413                    "%ul",
00414                    fcid);
00415 
00416   oid = PortableServer::string_to_ObjectId (oid_str);
00417 }

void TAO_PG_GenericFactory::poa ( PortableServer::POA_ptr  p  ) 

Set the POA to use when creating object references.

Definition at line 331 of file PG_GenericFactory.cpp.

References ACE_ASSERT, CORBA::is_nil(), and poa_.

00332 {
00333   ACE_ASSERT (CORBA::is_nil (this->poa_.in ())
00334               && !CORBA::is_nil (p));
00335 
00336   this->poa_ = PortableServer::POA::_duplicate (p);
00337 }

void TAO_PG_GenericFactory::populate_object_group ( PortableGroup::ObjectGroup_ptr  object_group,
const char *  type_id,
const PortableGroup::FactoryInfos factory_infos,
PortableGroup::InitialNumberMembersValue  initial_number_members,
TAO_PG_Factory_Set factory_set 
) [private]

Populate the object group being created. Called when the infrastructure-controlled membership style is used for the object group being created.

Definition at line 340 of file PG_GenericFactory.cpp.

References create_member(), CORBA::is_nil(), ACE_Array_Base< T >::size(), PortableGroup::FactoryInfo::the_factory, and PortableGroup::FactoryInfo::the_location.

Referenced by create_object().

00346 {
00347   CORBA::ULong factory_infos_count = factory_infos.length ();
00348   factory_set.size (factory_infos_count);
00349 
00350   for (CORBA::ULong j = 0; j < factory_infos_count; ++j)
00351     {
00352       TAO_PG_Factory_Node & factory_node = factory_set[j];
00353 
00354       const PortableGroup::FactoryInfo &factory_info = factory_infos[j];
00355 
00356       if (j < static_cast<CORBA::ULong> (initial_number_members))
00357         {
00358           PortableGroup::GenericFactory_ptr factory =
00359             factory_info.the_factory.in ();
00360 
00361           if (CORBA::is_nil (factory))
00362             {
00363               // @@ instead InvalidProperty?
00364               throw PortableGroup::NoFactory (
00365                 factory_info.the_location,
00366                 type_id);
00367             }
00368 
00369           // Do not allow the PortableGroup::MemberAlreadyPresent
00370           // exception to be propagated to this scope.
00371           const CORBA::Boolean propagate_member_already_present = 0;
00372 
00373           factory_node.factory_creation_id =
00374             this->create_member (object_group,
00375                                  factory_info,
00376                                  type_id,
00377                                  propagate_member_already_present);
00378         }
00379 
00380       factory_node.factory_info = factory_info;  // Memberwise copy
00381     }
00382 }

void TAO_PG_GenericFactory::process_criteria ( const char *  type_id,
const PortableGroup::Criteria criteria,
PortableGroup::MembershipStyleValue membership_style,
PortableGroup::FactoriesValue factory_infos,
PortableGroup::InitialNumberMembersValue initial_number_members,
PortableGroup::MinimumNumberMembersValue minimum_number_members 
) [private]

Only the MemberShipStyle, Factories, InitialNumberMembers and MinimumNumberMembers criteria/properties are defined by the PortableGroup IDL. Other services that implement the GenericFactory interface, such as load balancing and fault tolerance, may choose to support more.

The extracted criteria are object group-specific. In particular, they are the object group creation time criteria.

Definition at line 420 of file PG_GenericFactory.cpp.

References TAO_PG::get_property_value(), TAO_PG_PropertyManager::get_type_properties(), PortableGroup::MEMB_APP_CTRL, PortableGroup::MEMB_INF_CTRL, TAO_PG::override_properties(), property_manager_, and CORBA::string_dup().

Referenced by create_object().

00427 {
00428   // Get type-specific properties.
00429   PortableGroup::Properties_var props =
00430     this->property_manager_.get_type_properties (type_id);
00431 
00432   // Merge the given criteria with the type-specific criteria.
00433   TAO_PG::override_properties (criteria, props.inout ());
00434 
00435   PortableGroup::Criteria unmet_criteria;
00436   unmet_criteria.length (4);  // The four criteria understood by this
00437                               // method.
00438 
00439   // Unmet criteria count.
00440   CORBA::ULong uc = 0;
00441 
00442   PortableGroup::Name name (1);
00443   name.length (1);
00444 
00445   PortableGroup::Value value;
00446   PortableGroup::Value value1;
00447   PortableGroup::Value value2;
00448   PortableGroup::Value value3;
00449 
00450   // MembershipStyle
00451   name[0].id = CORBA::string_dup ("org.omg.PortableGroup.MembershipStyle");
00452   if (TAO_PG::get_property_value (name, props.in (), value)
00453       && (!(value >>= membership_style)
00454           || (membership_style != PortableGroup::MEMB_APP_CTRL
00455               && membership_style != PortableGroup::MEMB_INF_CTRL)))
00456     {
00457       // This only occurs if extraction of the actual value from the
00458       // Any fails.
00459       throw PortableGroup::InvalidProperty (name, value);
00460     }
00461 
00462   // Factories
00463   const PortableGroup::FactoryInfos * factory_infos_tmp = 0;
00464   name[0].id = CORBA::string_dup ("org.omg.PortableGroup.Factories");
00465   if (TAO_PG::get_property_value (name, props.in (), value1)
00466       && !(value1 >>= factory_infos_tmp))
00467     {
00468       // This only occurs if extraction of the actual value from the
00469       // Any fails.
00470       throw PortableGroup::InvalidProperty (name, value1);
00471     }
00472 
00473   const CORBA::ULong factory_infos_count =
00474     (factory_infos_tmp == 0 ? 0 : factory_infos_tmp->length ());
00475 
00476   // InitialNumberMembers
00477   name[0].id =
00478     CORBA::string_dup ("org.omg.PortableGroup.InitialNumberMembers");
00479   if (TAO_PG::get_property_value (name, props.in (), value2)
00480       && !(value2 >>= initial_number_members))
00481     {
00482       // This only occurs if extraction of the actual value from the
00483       // Any fails.
00484       throw PortableGroup::InvalidProperty (name, value2);
00485     }
00486 
00487   if (membership_style == PortableGroup::MEMB_INF_CTRL)
00488     {
00489       // If the number of factories is less than the initial number of
00490       // members or the desired number of initial members cannot
00491       // possibly be created.
00492 
00493       if (factory_infos_count < static_cast<CORBA::ULong> (initial_number_members))
00494         {
00495           unmet_criteria[uc].nam = name;
00496           unmet_criteria[uc++].val = value2;
00497         }
00498     }
00499 
00500   // MinimumNumberMembers
00501   name[0].id =
00502     CORBA::string_dup ("org.omg.PortableGroup.MinimumNumberMembers");
00503   if (TAO_PG::get_property_value (name, props.in (), value3)
00504       && !(value3 >>= minimum_number_members))
00505     {
00506       // This only occurs if extraction of the actual value from the
00507       // Any fails.
00508       throw PortableGroup::InvalidProperty (name, value3);
00509     }
00510 
00511   // If the minimum number of members is less than the initial number
00512   // of members, the MinimumNumberMembers property is cannot be
00513   // initially met.
00514   //
00515   // @note This code is not part of the above "MEMB_INF_CTRL" criteria
00516   //       check since the "name" and "value" variables have been
00517   //       changed.
00518   if (membership_style == PortableGroup::MEMB_INF_CTRL)
00519     {
00520       if (minimum_number_members < initial_number_members
00521           || static_cast<CORBA::ULong> (minimum_number_members) > factory_infos_count)
00522         {
00523           unmet_criteria[uc].nam = name;
00524           unmet_criteria[uc++].val = value3;
00525         }
00526       else if (factory_infos_tmp != 0)
00527       {
00528         factory_infos.length (factory_infos_count);
00529         factory_infos = *factory_infos_tmp;
00530       }
00531     }
00532 
00533   if (uc > 0)
00534     {
00535       // Reduce the length of the unmet criteria sequence in an effort
00536       // to optimize the copying that will occur when the below
00537       // exception is thrown.  Reducing the length is fast since no
00538       // deallocations should occur.
00539       unmet_criteria.length (uc);
00540 
00541       throw PortableGroup::CannotMeetCriteria (unmet_criteria);
00542     }
00543 }


Member Data Documentation

TAO_PG_Factory_Map TAO_PG_GenericFactory::factory_map_ [private]

Table that maps FactoryCreationId to TAO_PG_Factory_Set.

The TAO_PG_Factory_Set corresponding to a given FactoryCreationId contains the information necessary to clean up objects (members) that were created by the infrastructure, i.e. this GenericFactory. For example, this GenericFactory will invoke other application defined GenericFactorys when creating new object group members. The information returned from those application defined GenericFactorys is stored in a TAO_PG_Factory_Set, and thus this table.

Definition at line 202 of file PG_GenericFactory.h.

Referenced by ~TAO_PG_GenericFactory().

TAO_SYNCH_MUTEX TAO_PG_GenericFactory::lock_ [private]

Lock used to synchronize access to the factory creation id index (i.e. next_fcid_).

Definition at line 217 of file PG_GenericFactory.h.

CORBA::ULong TAO_PG_GenericFactory::next_fcid_ [private]

Value that is used when assigning a FactoryCreationId to the factory that was used to create a given ObjectGroup. The FactoryCreationId is typically comprised of this value in addition to another value that makes it unique to a given Load Balancer.

Definition at line 213 of file PG_GenericFactory.h.

Referenced by create_object().

TAO_PG_ObjectGroupManager& TAO_PG_GenericFactory::object_group_manager_ [private]

Reference to the ObjectGroup map.

Definition at line 186 of file PG_GenericFactory.h.

Referenced by check_minimum_number_members(), create_member(), create_object(), and delete_object().

PortableServer::POA_var TAO_PG_GenericFactory::poa_ [private]

Reference to the POA used to create object group references.

Definition at line 183 of file PG_GenericFactory.h.

Referenced by poa().

TAO_PG_PropertyManager& TAO_PG_GenericFactory::property_manager_ [private]

Reference to the PropertyManager.

Definition at line 189 of file PG_GenericFactory.h.

Referenced by check_minimum_number_members(), create_object(), and process_criteria().


The documentation for this class was generated from the following files:
Generated on Tue Feb 2 17:50:00 2010 for TAO_PortableGroup by  doxygen 1.4.7