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) throw (CORBA::SystemException, PortableGroup::NoFactory, PortableGroup::ObjectNotCreated, PortableGroup::InvalidCriteria, PortableGroup::InvalidProperty, PortableGroup::CannotMeetCriteria, PortableGroup::MemberAlreadyPresent)
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) throw (CORBA::SystemException, PortableGroup::NoFactory, PortableGroup::ObjectNotCreated, PortableGroup::InvalidCriteria, PortableGroup::InvalidProperty, PortableGroup::CannotMeetCriteria)
virtual void delete_object (const PortableGroup::GenericFactory::FactoryCreationId &factory_creation_id) throw (CORBA::SystemException, PortableGroup::ObjectNotFound)

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.

References TAO_PG_ObjectGroupManager::generic_factory(), object_group_manager_, and TAO_PG_MAX_OBJECT_GROUPS.

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 ACE_CATCHANY, ACE_DECLARE_NEW_CORBA_ENV, ACE_ENDTRY, ACE_ENV_ARG_PARAMETER, ACE_TRY, ACE_TRY_CHECK, delete_object_i(), factory_map_, and TAO_PG_Factory_Set.

00033 {
00034   ACE_DECLARE_NEW_CORBA_ENV;
00035 
00036   TAO_PG_Factory_Map::iterator end = this->factory_map_.end ();
00037   for (TAO_PG_Factory_Map::iterator i = this->factory_map_.begin ();
00038        i != end;
00039        ++i)
00040     {
00041       TAO_PG_Factory_Set & factory_set = (*i).int_id_;
00042 
00043       ACE_TRY
00044         {
00045           this->delete_object_i (factory_set,
00046                                  1 /* Ignore exceptions */
00047                                  ACE_ENV_ARG_PARAMETER);
00048           ACE_TRY_CHECK;
00049         }
00050       ACE_CATCHANY
00051         {
00052           // Ignore all exceptions.
00053         }
00054       ACE_ENDTRY;
00055     }
00056 
00057   (void) this->factory_map_.close ();
00058 }


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 593 of file PG_GenericFactory.cpp.

References ACE_CATCH, ACE_CHECK, ACE_ENDTRY, ACE_ENV_ARG_PARAMETER, ACE_THROW, ACE_TRY, ACE_TRY_CHECK, create_member(), TAO_PG_Factory_Node::factory_creation_id, TAO_PG_Factory_Node::factory_info, factory_map_, PortableGroup::GenericFactory::FactoryCreationId, TAO_PG_PropertyManager::get_properties(), TAO_PG::get_property_value(), TAO_PG_ObjectGroupManager::member_count(), PortableGroup::MinimumNumberMembersValue, object_group_manager_, property_manager_, ACE_Array_Base< T >::size(), CORBA::string_dup(), TAO_PG_Factory_Set, and PortableGroup::Value.

00598 {
00599   // Check if we've dropped below the MinimumNumberMembers threshold.
00600   // If so, attempt to create enough new members to fill the gap.
00601 
00602   // If no entry exists in the factory map, infrastructure (this
00603   // GenericFactory implementation) controlled membership was not
00604   // used.
00605   TAO_PG_Factory_Map::ENTRY *entry = 0;
00606   if (this->factory_map_.find (group_id, entry) != 0)
00607     return;
00608 
00609   TAO_PG_Factory_Set & factory_set = entry->int_id_;
00610 
00611   PortableGroup::Properties_var props =
00612     this->property_manager_.get_properties (object_group
00613                                             ACE_ENV_ARG_PARAMETER);
00614   ACE_CHECK;
00615 
00616   PortableGroup::Name name (1);
00617   name.length (1);
00618 
00619   PortableGroup::Value value;
00620 
00621   // MinimumNumberMembers
00622   name[0].id =
00623     CORBA::string_dup ("org.omg.PortableGroup.MinimumNumberMembers");
00624 
00625   PortableGroup::MinimumNumberMembersValue minimum_number_members;
00626 
00627   if (TAO_PG::get_property_value (name, props.in (), value))
00628     {
00629       if (!(value >>= minimum_number_members))
00630         {
00631           // This only occurs if extraction of the actual value from
00632           // the Any fails.  It shouldn't fail at this point.
00633           ACE_THROW (CORBA::INTERNAL ());
00634         }
00635 
00636       const CORBA::ULong count =
00637         this->object_group_manager_.member_count (object_group
00638                                                   ACE_ENV_ARG_PARAMETER);
00639       ACE_CHECK;
00640 
00641       if (count >= static_cast<CORBA::ULong> (minimum_number_members))
00642         return;
00643 
00644       const CORBA::ULong gap =
00645         static_cast<CORBA::ULong> (minimum_number_members) - count;
00646 
00647       CORBA::ULong creation_count = 0;
00648 
00649       const size_t len = factory_set.size ();
00650 
00651       static const PortableGroup::GenericFactory::FactoryCreationId *
00652         nil_fcid = 0;
00653 
00654       for (size_t i = 0; i < len; ++i)
00655         {
00656           TAO_PG_Factory_Node & node = factory_set[i];
00657 
00658           PortableGroup::GenericFactory::FactoryCreationId * const tmp_fcid =
00659             node.factory_creation_id;
00660 
00661           // Check if the application supplied GenericFactory was
00662           // already invoked.
00663           if (tmp_fcid != nil_fcid)
00664             continue;
00665 
00666           ACE_TRY
00667             {
00668               const CORBA::Boolean propagate_member_already_present = 1;
00669 
00670               node.factory_creation_id =
00671                 this->create_member (object_group,
00672                                      node.factory_info,
00673                                      type_id,
00674                                      propagate_member_already_present
00675                                      ACE_ENV_ARG_PARAMETER);
00676               ACE_TRY_CHECK;
00677 
00678               ++creation_count;
00679 
00680               // Check if the MinimumNumberMembers threshold gap has
00681               // been filled.
00682               if (gap == creation_count)
00683                 return;
00684             }
00685           ACE_CATCH (PortableGroup::MemberAlreadyPresent, ex)
00686             {
00687               // Ignore this exception and continue.
00688             }
00689           ACE_ENDTRY;
00690           ACE_CHECK;
00691         }
00692 
00693       // @todo If we get this far, and the MinimumNumberMembers
00694       //       threshold gap hasn't been filled, what do we do?  Throw
00695       //       a CORBA::TRANSIENT?
00696     }
00697 }

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
throw (CORBA::SystemException, PortableGroup::NoFactory, PortableGroup::ObjectNotCreated, PortableGroup::InvalidCriteria, PortableGroup::InvalidProperty, PortableGroup::CannotMeetCriteria, PortableGroup::MemberAlreadyPresent)
 

Note:
This method is only used by the infrastructure.

Definition at line 700 of file PG_GenericFactory.cpp.

References ACE_CATCHANY, ACE_CHECK_RETURN, ACE_ENDTRY, ACE_ENV_ARG_PARAMETER, ACE_RE_THROW, ACE_TRY, ACE_TRY_CHECK, ACE_TRY_THROW, and CORBA::is_nil().

Referenced by check_minimum_number_members(), and populate_object_group().

00713 {
00714   PortableGroup::GenericFactory::FactoryCreationId_var fcid;
00715 
00716   CORBA::Object_var member =
00717     factory_info.the_factory->create_object (type_id,
00718                                              factory_info.the_criteria,
00719                                              fcid.out ()
00720                                              ACE_ENV_ARG_PARAMETER);
00721   ACE_CHECK_RETURN (0);
00722 
00723   ACE_TRY
00724     {
00725       // @@ Should an "_is_a()" be performed here?  While it
00726       //    appears to be the right thing to do, it can be
00727       //    expensive.
00728       //
00729       // Make sure an Object of the correct type was created.
00730       // It is possible that an object of the wrong type was
00731       // created if the type_id parameter does not match the
00732       // type of object the GenericFactory creates.
00733       CORBA::Boolean right_type_id =
00734         member->_is_a (type_id
00735                        ACE_ENV_ARG_PARAMETER);
00736       ACE_TRY_CHECK;
00737 
00738       // @todo Strategize this -- e.g. strict type checking.
00739       if (!right_type_id)
00740         {
00741           // An Object of incorrect type was created.  Delete
00742           // it, and throw a NoFactory exception.
00743           factory_info.the_factory->delete_object (fcid.in ()
00744                                                    ACE_ENV_ARG_PARAMETER);
00745           ACE_TRY_CHECK;
00746 
00747           ACE_TRY_THROW (PortableGroup::NoFactory (factory_info.the_location,
00748                                                    type_id));
00749         }
00750 
00751       this->object_group_manager_._tao_add_member (
00752         object_group,
00753         factory_info.the_location,
00754         member.in (),
00755         type_id,
00756         propagate_member_already_present
00757         ACE_ENV_ARG_PARAMETER);
00758       ACE_TRY_CHECK;
00759     }
00760   ACE_CATCHANY
00761     {
00762       // If the member reference is not nil, then the factory
00763       // was successfully invoked.  Since an exception was
00764       // thrown, clean up the up created member.
00765       if (!CORBA::is_nil (member.in ()))
00766         {
00767           factory_info.the_factory->delete_object (fcid.in ()
00768                                                    ACE_ENV_ARG_PARAMETER);
00769           ACE_TRY_CHECK;
00770         }
00771 
00772       ACE_RE_THROW;
00773     }
00774   ACE_ENDTRY;
00775   ACE_CHECK_RETURN (0);
00776 
00777   return fcid._retn ();
00778 }

CORBA::Object_ptr TAO_PG_GenericFactory::create_object const char *  type_id,
const PortableGroup::Criteria the_criteria,
PortableGroup::GenericFactory::FactoryCreationId_out  factory_creation_id
throw (CORBA::SystemException, PortableGroup::NoFactory, PortableGroup::ObjectNotCreated, PortableGroup::InvalidCriteria, PortableGroup::InvalidProperty, PortableGroup::CannotMeetCriteria) [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 61 of file PG_GenericFactory.cpp.

References ACE_CATCHANY, ACE_CHECK_RETURN, ACE_ENDTRY, ACE_ENV_ARG_PARAMETER, ACE_GUARD_RETURN, ACE_NEW_THROW_EX, ACE_RE_THROW, ACE_THROW_RETURN, ACE_TRY, ACE_TRY_CHECK, ACE_TRY_THROW, PortableGroup::Criteria, PortableGroup::FactoriesValue, PortableGroup::GenericFactory::FactoryCreationId, PortableGroup::InitialNumberMembersValue, PortableGroup::MembershipStyleValue, PortableGroup::MinimumNumberMembersValue, TAO_PG_Factory_Set, TAO_PG_INITIAL_NUMBER_MEMBERS, TAO_PG_MEMBERSHIP_STYLE, TAO_PG_MINIMUM_NUMBER_MEMBERS, and TAO_SYNCH_MUTEX.

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

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 312 of file PG_GenericFactory.cpp.

References ACE_CHECK, ACE_ENV_ARG_PARAMETER, ACE_GUARD, TAO_PG_Factory_Node::factory_creation_id, TAO_PG_Factory_Node::factory_info, factory_map_, PortableGroup::Location, ACE_Array_Base< T >::size(), TAO_PG_Factory_Set, TAO_SYNCH_MUTEX, PortableGroup::FactoryInfo::the_factory, and PortableGroup::FactoryInfo::the_location.

00316 {
00317   ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00318 
00319   // If no entry exists in the factory map, infrastructure
00320   // controlled membership was not used.
00321   TAO_PG_Factory_Map::ENTRY *entry = 0;
00322   if (this->factory_map_.find (group_id, entry) == 0)
00323     {
00324       TAO_PG_Factory_Set & factory_set = entry->int_id_;
00325 
00326       const size_t len = factory_set.size ();
00327 
00328       // Iterate through the factory_set until a location match
00329       // occurs.  If a location match occurs, the member was created
00330       // by the infrastructure, i.e. this GenericFactory
00331       // implementation.  If no location matches, the member was
00332       // created by the application, and no operation will be
00333       // performed.
00334       //
00335       // @todo This is linear search.  Change to use a container with
00336       //       better search times.
00337       for (size_t i = 0; i < len; ++i)
00338         {
00339           TAO_PG_Factory_Node & node = factory_set[i];
00340           PortableGroup::FactoryInfo & info = node.factory_info;
00341 
00342           if (info.the_location == location)
00343             {
00344               info.the_factory->delete_object (node.factory_creation_id.in ()
00345                                                ACE_ENV_ARG_PARAMETER);
00346               ACE_CHECK;
00347 
00348               // The member has been successfully deleted.  Reduce the
00349               // size of the factory_set accordingly.
00350               if (len > 1)
00351                 {
00352                   // Move the last element to the location of the
00353                   // current one and reduce the size of the set by
00354                   // one.
00355                   const size_t new_len = len - 1;
00356                   node = factory_set[new_len]; // Memberwise copy
00357                   factory_set.size (new_len);
00358                 }
00359               else
00360                 {
00361                   // A copy isn't necessary if the last member was
00362                   // deleted.
00363                   factory_set.size (0);
00364                 }
00365 
00366               return;
00367             }
00368         }
00369     }
00370 }

void TAO_PG_GenericFactory::delete_object const PortableGroup::GenericFactory::FactoryCreationId factory_creation_id  )  throw (CORBA::SystemException, PortableGroup::ObjectNotFound) [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 211 of file PG_GenericFactory.cpp.

References ACE_CHECK, ACE_ENV_ARG_PARAMETER, ACE_GUARD, ACE_THROW, PortableGroup::GenericFactory::FactoryCreationId, TAO_PG_Factory_Set, and TAO_SYNCH_MUTEX.

00217 {
00218   CORBA::ULong fcid = 0;
00219 
00220   if (factory_creation_id >>= fcid) // Extract the actual FactoryCreationId.
00221     {
00222       // Successfully extracted the FactoryCreationId.  Now find the
00223       // TAO_PG_Factory_Set corresponding to it.
00224 
00225       ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);
00226 
00227       // If no entry exists in the factory map, infrastructure
00228       // controlled membership was not used.
00229       TAO_PG_Factory_Map::ENTRY *entry = 0;
00230       if (this->factory_map_.find (fcid, entry) == 0)
00231         {
00232           TAO_PG_Factory_Set & factory_set = entry->int_id_;
00233 
00234           this->delete_object_i (factory_set,
00235                                  0  /* Do not ignore exceptions */
00236                                  ACE_ENV_ARG_PARAMETER);
00237           ACE_CHECK;
00238 
00239           if (this->factory_map_.unbind (fcid) != 0)
00240             ACE_THROW (CORBA::INTERNAL ());
00241         }
00242     }
00243   else
00244     ACE_THROW (PortableGroup::ObjectNotFound ());  // @@
00245                                                    //    CORBA::BAD_PARAM
00246                                                    //    instead?
00247 
00248   // The ObjectId for the newly created object group is comprised
00249   // solely of the FactoryCreationId.
00250   PortableServer::ObjectId_var oid;
00251   this->get_ObjectId (fcid, oid.out ());
00252 
00253   // Destroy the object group entry.
00254   this->object_group_manager_.destroy_object_group (
00255     oid.in ()
00256     ACE_ENV_ARG_PARAMETER);
00257   ACE_CHECK;
00258 }

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 261 of file PG_GenericFactory.cpp.

References ACE_CATCHANY, ACE_CHECK, ACE_ENDTRY, ACE_ENV_ARG_PARAMETER, ACE_RE_THROW, ACE_TRY, ACE_TRY_CHECK, TAO_PG_Factory_Node::factory_creation_id, TAO_PG_Factory_Node::factory_info, PortableGroup::GenericFactory::FactoryCreationId, ACE_Array_Base< T >::size(), TAO_PG_Factory_Set, and PortableGroup::FactoryInfo::the_factory.

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

00264 {
00265   const size_t len = factory_set.size ();
00266 
00267   size_t ilen = len;
00268   for (size_t i = 0; i != len; ++i)
00269     {
00270       // Destroy the object group member in reverse order in case the
00271       // array list is only partially destroyed and another call to
00272       // GenericFactory::delete_object() occurs afterwards.
00273       --ilen;
00274 
00275       TAO_PG_Factory_Node & factory_node = factory_set[ilen];
00276 
00277       PortableGroup::GenericFactory_ptr factory =
00278         factory_node.factory_info.the_factory.in ();
00279       const PortableGroup::GenericFactory::FactoryCreationId & member_fcid =
00280         factory_node.factory_creation_id.in ();
00281 
00282       ACE_TRY
00283         {
00284           factory->delete_object (member_fcid
00285                                   ACE_ENV_ARG_PARAMETER);
00286           ACE_TRY_CHECK;
00287         }
00288       ACE_CATCHANY
00289         {
00290           // Exceptions are generally only ignored when this
00291           // GenericFactory (not the one being invoked above) is
00292           // destroyed.  The idea is to allow the GenericFactory to be
00293           // destroyed regardless of whether or not all object group
00294           // members have been destroyed, and minimize the number of
00295           // object group members that have not been destroyed.
00296           if (!ignore_exceptions)
00297             ACE_RE_THROW;
00298         }
00299       ACE_ENDTRY;
00300       ACE_CHECK;
00301 
00302       // Since GenericFactory::delete_object() can throw an exception,
00303       // decrease the size of the factory array incrementally since
00304       // some object group members may not have been destroyed yet.
00305       // Note that this size reduction is fast since no memory is
00306       // actually deallocated.
00307       factory_set.size (ilen);
00308     }
00309 }

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 is also returned.

Definition at line 429 of file PG_GenericFactory.cpp.

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

00432 {
00433   // Since the POA used by the LoadManager uses the NON_RETAIN
00434   // policy, explicitly choose an ObjectId that is unique to a given
00435   // type.
00436 
00437   // Make the ObjectId be the next value of the number of types that
00438   // have been registered with the LoadManager.  For example, if two
00439   // types of objects have been registered with the LoadManager, then
00440   // the ObjectId for the object currently being registered will be
00441   // "3" since the object will be the third type of object registered
00442   // with the LoadManager.  Previously used values will not be reused
00443   // to ensure that a ServantLocator does not inadvertently return a
00444   // reference to an object that had a previously used ObjectId.
00445   // Specifcally, the numerical value used for the ObjectId increases
00446   // monotonically.
00447 
00448   // 4294967295UL -- Largest 32 bit unsigned integer
00449   // 123456789012 -- 10 digits
00450   //                + 2 for "UL"  (unnecessary, but let's be safe)
00451   //                + 1 for null terminator
00452   //                + 1 for good luck. :-)
00453   const size_t MAX_OID_LEN = 14;
00454 
00455   char oid_str[MAX_OID_LEN] = { 0 };
00456   ACE_OS::sprintf (oid_str,
00457                    "%ul",
00458                    fcid);
00459 
00460   oid = PortableServer::string_to_ObjectId (oid_str);
00461 }

void TAO_PG_GenericFactory::poa PortableServer::POA_ptr  p  ) 
 

Set the POA to use when creating object references.

Definition at line 373 of file PG_GenericFactory.cpp.

References ACE_ASSERT, and CORBA::is_nil().

00374 {
00375   ACE_ASSERT (CORBA::is_nil (this->poa_.in ())
00376               && !CORBA::is_nil (p));
00377 
00378   this->poa_ = PortableServer::POA::_duplicate (p);
00379 }

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 382 of file PG_GenericFactory.cpp.

References ACE_CHECK, ACE_ENV_ARG_PARAMETER, ACE_THROW, create_member(), TAO_PG_Factory_Node::factory_creation_id, TAO_PG_Factory_Node::factory_info, PortableGroup::FactoryInfos, PortableGroup::InitialNumberMembersValue, CORBA::is_nil(), TAO_PG_Factory_Set, PortableGroup::FactoryInfo::the_factory, and PortableGroup::FactoryInfo::the_location.

00389 {
00390   CORBA::ULong factory_infos_count = factory_infos.length ();
00391   factory_set.size (factory_infos_count);
00392 
00393   for (CORBA::ULong j = 0; j < factory_infos_count; ++j)
00394     {
00395       TAO_PG_Factory_Node & factory_node = factory_set[j];
00396 
00397       const PortableGroup::FactoryInfo &factory_info = factory_infos[j];
00398 
00399       if (j < static_cast<CORBA::ULong> (initial_number_members))
00400         {
00401           PortableGroup::GenericFactory_ptr factory =
00402             factory_info.the_factory.in ();
00403 
00404           if (CORBA::is_nil (factory))
00405             {
00406               // @@ instead InvalidProperty?
00407               ACE_THROW (PortableGroup::NoFactory (factory_info.the_location,
00408                                                    type_id));
00409             }
00410 
00411           // Do not allow the PortableGroup::MemberAlreadyPresent
00412           // exception to be propagated to this scope.
00413           const CORBA::Boolean propagate_member_already_present = 0;
00414 
00415           factory_node.factory_creation_id =
00416             this->create_member (object_group,
00417                                  factory_info,
00418                                  type_id,
00419                                  propagate_member_already_present
00420                                  ACE_ENV_ARG_PARAMETER);
00421           ACE_CHECK;
00422         }
00423 
00424       factory_node.factory_info = factory_info;  // Memberwise copy
00425     }
00426 }

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 464 of file PG_GenericFactory.cpp.

References ACE_CHECK, ACE_ENV_ARG_PARAMETER, ACE_THROW, PortableGroup::Criteria, PortableGroup::FactoriesValue, PortableGroup::FactoryInfos, TAO_PG::get_property_value(), TAO_PG_PropertyManager::get_type_properties(), PortableGroup::InitialNumberMembersValue, PortableGroup::MembershipStyleValue, PortableGroup::MinimumNumberMembersValue, TAO_PG::override_properties(), property_manager_, CORBA::string_dup(), and PortableGroup::Value.

00472 {
00473   // Get type-specific properties.
00474   PortableGroup::Properties_var props =
00475     this->property_manager_.get_type_properties (type_id
00476                                                  ACE_ENV_ARG_PARAMETER);
00477   ACE_CHECK;
00478 
00479   // Merge the given criteria with the type-specific criteria.
00480   TAO_PG::override_properties (criteria, props.inout ());
00481 
00482   PortableGroup::Criteria unmet_criteria;
00483   unmet_criteria.length (4);  // The four criteria understood by this
00484                               // method.
00485 
00486   // Unmet criteria count.
00487   CORBA::ULong uc = 0;
00488 
00489   PortableGroup::Name name (1);
00490   name.length (1);
00491 
00492   PortableGroup::Value value;
00493   PortableGroup::Value value1;
00494   PortableGroup::Value value2;
00495   PortableGroup::Value value3;
00496 
00497   // MembershipStyle
00498   name[0].id = CORBA::string_dup ("org.omg.PortableGroup.MembershipStyle");
00499   if (TAO_PG::get_property_value (name, props.in (), value)
00500       && (!(value >>= membership_style)
00501           || (membership_style != PortableGroup::MEMB_APP_CTRL
00502               && membership_style != PortableGroup::MEMB_INF_CTRL)))
00503     {
00504       // This only occurs if extraction of the actual value from the
00505       // Any fails.
00506       ACE_THROW (PortableGroup::InvalidProperty (name, value));
00507     }
00508 
00509   // Factories
00510   const PortableGroup::FactoryInfos * factory_infos_tmp = 0;
00511   name[0].id = CORBA::string_dup ("org.omg.PortableGroup.Factories");
00512   if (TAO_PG::get_property_value (name, props.in (), value1)
00513       && !(value1 >>= factory_infos_tmp))
00514     {
00515       // This only occurs if extraction of the actual value from the
00516       // Any fails.
00517       ACE_THROW (PortableGroup::InvalidProperty (name, value1));
00518     }
00519 
00520   const CORBA::ULong factory_infos_count =
00521     (factory_infos_tmp == 0 ? 0 : factory_infos_tmp->length ());
00522 
00523   // InitialNumberMembers
00524   name[0].id =
00525     CORBA::string_dup ("org.omg.PortableGroup.InitialNumberMembers");
00526   if (TAO_PG::get_property_value (name, props.in (), value2)
00527       && !(value2 >>= initial_number_members))
00528     {
00529       // This only occurs if extraction of the actual value from the
00530       // Any fails.
00531       ACE_THROW (PortableGroup::InvalidProperty (name, value2));
00532     }
00533 
00534   if (membership_style == PortableGroup::MEMB_INF_CTRL)
00535     {
00536       // If the number of factories is less than the initial number of
00537       // members or the desired number of initial members cannot
00538       // possibly be created.
00539 
00540       if (factory_infos_count < static_cast<CORBA::ULong> (initial_number_members))
00541         {
00542           unmet_criteria[uc].nam = name;
00543           unmet_criteria[uc++].val = value2;
00544         }
00545     }
00546 
00547   // MinimumNumberMembers
00548   name[0].id =
00549     CORBA::string_dup ("org.omg.PortableGroup.MinimumNumberMembers");
00550   if (TAO_PG::get_property_value (name, props.in (), value3)
00551       && !(value3 >>= minimum_number_members))
00552     {
00553       // This only occurs if extraction of the actual value from the
00554       // Any fails.
00555       ACE_THROW (PortableGroup::InvalidProperty (name, value3));
00556     }
00557 
00558   // If the minimum number of members is less than the initial number
00559   // of members, the MinimumNumberMembers property is cannot be
00560   // initially met.
00561   //
00562   // @note This code is not part of the above "MEMB_INF_CTRL" criteria
00563   //       check since the "name" and "value" variables have been
00564   //       changed.
00565   if (membership_style == PortableGroup::MEMB_INF_CTRL)
00566     {
00567       if (minimum_number_members < initial_number_members
00568           || static_cast<CORBA::ULong> (minimum_number_members) > factory_infos_count)
00569         {
00570           unmet_criteria[uc].nam = name;
00571           unmet_criteria[uc++].val = value3;
00572         }
00573       else if (factory_infos_tmp != 0)
00574       {
00575         factory_infos.length (factory_infos_count);
00576         factory_infos = *factory_infos_tmp;
00577       }
00578     }
00579 
00580   if (uc > 0)
00581     {
00582       // Reduce the length of the unmet criteria sequence in an effort
00583       // to optimize the copying that will occur when the below
00584       // exception is thrown.  Reducing the length is fast since no
00585       // deallocations should occur.
00586       unmet_criteria.length (uc);
00587 
00588       ACE_THROW (PortableGroup::CannotMeetCriteria (unmet_criteria));
00589     }
00590 }


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 225 of file PG_GenericFactory.h.

Referenced by check_minimum_number_members(), delete_member(), and ~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 240 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 236 of file PG_GenericFactory.h.

TAO_PG_ObjectGroupManager& TAO_PG_GenericFactory::object_group_manager_ [private]
 

Reference to the ObjectGroup map.

Definition at line 209 of file PG_GenericFactory.h.

Referenced by check_minimum_number_members(), and TAO_PG_GenericFactory().

PortableServer::POA_var TAO_PG_GenericFactory::poa_ [private]
 

Reference to the POA used to create object group references.

Definition at line 206 of file PG_GenericFactory.h.

TAO_PG_PropertyManager& TAO_PG_GenericFactory::property_manager_ [private]
 

Reference to the PropertyManager.

Definition at line 212 of file PG_GenericFactory.h.

Referenced by check_minimum_number_members(), and process_criteria().


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 14:04:57 2006 for TAO_PortableGroup by doxygen 1.3.6