📄 pg_genericfactory.cpp
字号:
{
TAO_PG_Factory_Node & factory_node = factory_set[j];
const PortableGroup::FactoryInfo &factory_info = factory_infos[j];
if (j < ACE_static_cast (CORBA::ULong, initial_number_members))
{
PortableGroup::GenericFactory_ptr factory =
factory_info.the_factory.in ();
if (CORBA::is_nil (factory))
{
// @@ instead InvalidProperty?
ACE_THROW (PortableGroup::NoFactory (factory_info.the_location,
type_id));
}
// Do not allow the PortableGroup::MemberAlreadyPresent
// exception to be propagated to this scope.
const CORBA::Boolean propagate_member_already_present = 0;
factory_node.factory_creation_id =
this->create_member (object_group,
factory_info,
type_id,
propagate_member_already_present
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
factory_node.factory_info = factory_info; // Memberwise copy
}
}
void
TAO_PG_GenericFactory::get_ObjectId (
CORBA::ULong fcid,
PortableServer::ObjectId_out oid)
{
// Since the POA used by the LoadManager uses the NON_RETAIN
// policy, explicitly choose an ObjectId that is unique to a given
// type.
// Make the ObjectId be the next value of the number of types that
// have been registered with the LoadManager. For example, if two
// types of objects have been registered with the LoadManager, then
// the ObjectId for the object currently being registered will be
// "3" since the object will be the third type of object registered
// with the LoadManager. Previously used values will not be reused
// to ensure that a ServantLocator does not inadvertently return a
// reference to an object that had a previously used ObjectId.
// Specifcally, the numerical value used for the ObjectId increases
// monotonically.
// 4294967295UL -- Largest 32 bit unsigned integer
// 123456789012 -- 10 digits
// + 2 for "UL" (unnecessary, but let's be safe)
// + 1 for null terminator
// + 1 for good luck. :-)
const size_t MAX_OID_LEN = 14;
char oid_str[MAX_OID_LEN] = { 0 };
ACE_OS::sprintf (oid_str,
"%ul",
fcid);
oid = PortableServer::string_to_ObjectId (oid_str);
}
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
ACE_ENV_ARG_DECL)
{
// Get type-specific properties.
PortableGroup::Properties_var props =
this->property_manager_.get_type_properties (type_id
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// Merge the given criteria with the type-specific criteria.
TAO_PG::override_properties (criteria, props.inout ());
PortableGroup::Criteria unmet_criteria;
unmet_criteria.length (4); // The four criteria understood by this
// method.
// Unmet criteria count.
CORBA::ULong uc = 0;
PortableGroup::Name name (1);
name.length (1);
PortableGroup::Value value;
PortableGroup::Value value1;
PortableGroup::Value value2;
PortableGroup::Value value3;
// MembershipStyle
name[0].id = CORBA::string_dup ("org.omg.PortableGroup.MembershipStyle");
if (TAO_PG::get_property_value (name, props.in (), value)
&& (!(value >>= membership_style)
|| (membership_style != PortableGroup::MEMB_APP_CTRL
&& membership_style != PortableGroup::MEMB_INF_CTRL)))
{
// This only occurs if extraction of the actual value from the
// Any fails.
ACE_THROW (PortableGroup::InvalidProperty (name, value));
}
// Factories
const PortableGroup::FactoryInfos * factory_infos_tmp = 0;
name[0].id = CORBA::string_dup ("org.omg.PortableGroup.Factories");
if (TAO_PG::get_property_value (name, props.in (), value1)
&& !(value1 >>= factory_infos_tmp))
{
// This only occurs if extraction of the actual value from the
// Any fails.
ACE_THROW (PortableGroup::InvalidProperty (name, value1));
}
const CORBA::ULong factory_infos_count =
(factory_infos_tmp == 0 ? 0 : factory_infos_tmp->length ());
// InitialNumberMembers
name[0].id =
CORBA::string_dup ("org.omg.PortableGroup.InitialNumberMembers");
if (TAO_PG::get_property_value (name, props.in (), value2)
&& !(value2 >>= initial_number_members))
{
// This only occurs if extraction of the actual value from the
// Any fails.
ACE_THROW (PortableGroup::InvalidProperty (name, value2));
}
if (membership_style == PortableGroup::MEMB_INF_CTRL)
{
// If the number of factories is less than the initial number of
// members or the desired number of initial members cannot
// possibly be created.
if (factory_infos_count < ACE_static_cast (CORBA::ULong,
initial_number_members))
{
unmet_criteria[uc].nam = name;
unmet_criteria[uc++].val = value2;
}
}
// MinimumNumberMembers
name[0].id =
CORBA::string_dup ("org.omg.PortableGroup.MinimumNumberMembers");
if (TAO_PG::get_property_value (name, props.in (), value3)
&& !(value3 >>= minimum_number_members))
{
// This only occurs if extraction of the actual value from the
// Any fails.
ACE_THROW (PortableGroup::InvalidProperty (name, value3));
}
// If the minimum number of members is less than the initial number
// of members, the MinimumNumberMembers property is cannot be
// initially met.
//
// @note This code is not part of the above "MEMB_INF_CTRL" criteria
// check since the "name" and "value" variables have been
// changed.
if (membership_style == PortableGroup::MEMB_INF_CTRL)
{
if (minimum_number_members < initial_number_members
|| ACE_static_cast (CORBA::ULong,
minimum_number_members) > factory_infos_count)
{
unmet_criteria[uc].nam = name;
unmet_criteria[uc++].val = value3;
}
else if (factory_infos_tmp != 0)
{
factory_infos.length (factory_infos_count);
factory_infos = *factory_infos_tmp;
}
}
if (uc > 0)
{
// Reduce the length of the unmet criteria sequence in an effort
// to optimize the copying that will occur when the below
// exception is thrown. Reducing the length is fast since no
// deallocations should occur.
unmet_criteria.length (uc);
ACE_THROW (PortableGroup::CannotMeetCriteria (unmet_criteria));
}
}
void
TAO_PG_GenericFactory::check_minimum_number_members (
PortableGroup::ObjectGroup_ptr object_group,
CORBA::ULong group_id,
const char * type_id
ACE_ENV_ARG_DECL)
{
// Check if we've dropped below the MinimumNumberMembers threshold.
// If so, attempt to create enough new members to fill the gap.
// If no entry exists in the factory map, infrastructure (this
// GenericFactory implementation) controlled membership was not
// used.
TAO_PG_Factory_Map::ENTRY *entry = 0;
if (this->factory_map_.find (group_id, entry) != 0)
return;
TAO_PG_Factory_Set & factory_set = entry->int_id_;
PortableGroup::Properties_var props =
this->property_manager_.get_properties (object_group
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
PortableGroup::Name name (1);
name.length (1);
PortableGroup::Value value;
// MinimumNumberMembers
name[0].id =
CORBA::string_dup ("org.omg.PortableGroup.MinimumNumberMembers");
PortableGroup::MinimumNumberMembersValue minimum_number_members;
if (TAO_PG::get_property_value (name, props.in (), value))
{
if (!(value >>= minimum_number_members))
{
// This only occurs if extraction of the actual value from
// the Any fails. It shouldn't fail at this point.
ACE_THROW (CORBA::INTERNAL ());
}
const CORBA::ULong count =
this->object_group_manager_.member_count (object_group
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
if (count >= ACE_static_cast (CORBA::ULong, minimum_number_members))
return;
const CORBA::ULong gap =
ACE_static_cast (CORBA::ULong,
minimum_number_members) - count;
CORBA::ULong creation_count = 0;
const size_t len = factory_set.size ();
static const PortableGroup::GenericFactory::FactoryCreationId *
nil_fcid = 0;
for (size_t i = 0; i < len; ++i)
{
TAO_PG_Factory_Node & node = factory_set[i];
PortableGroup::GenericFactory::FactoryCreationId * const tmp_fcid =
node.factory_creation_id;
// Check if the application supplied GenericFactory was
// already invoked.
if (tmp_fcid != nil_fcid)
continue;
ACE_TRY
{
const CORBA::Boolean propagate_member_already_present = 1;
node.factory_creation_id =
this->create_member (object_group,
node.factory_info,
type_id,
propagate_member_already_present
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
++creation_count;
// Check if the MinimumNumberMembers threshold gap has
// been filled.
if (gap == creation_count)
return;
}
ACE_CATCH (PortableGroup::MemberAlreadyPresent, ex)
{
// Ignore this exception and continue.
}
ACE_ENDTRY;
ACE_CHECK;
}
// @todo If we get this far, and the MinimumNumberMembers
// threshold gap hasn't been filled, what do we do? Throw
// a CORBA::TRANSIENT?
}
}
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
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException,
PortableGroup::NoFactory,
PortableGroup::ObjectNotCreated,
PortableGroup::InvalidCriteria,
PortableGroup::InvalidProperty,
PortableGroup::CannotMeetCriteria,
PortableGroup::MemberAlreadyPresent))
{
PortableGroup::GenericFactory::FactoryCreationId_var fcid;
CORBA::Object_var member =
factory_info.the_factory->create_object (type_id,
factory_info.the_criteria,
fcid.out ()
ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (0);
ACE_TRY
{
// @@ Should an "_is_a()" be performed here? While it
// appears to be the right thing to do, it can be
// expensive.
//
// Make sure an Object of the correct type was created.
// It is possible that an object of the wrong type was
// created if the type_id parameter does not match the
// type of object the GenericFactory creates.
CORBA::Boolean right_type_id =
member->_is_a (type_id
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
// @todo Strategize this -- e.g. strict type checking.
if (!right_type_id)
{
// An Object of incorrect type was created. Delete
// it, and throw a NoFactory exception.
factory_info.the_factory->delete_object (fcid.in ()
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
ACE_TRY_THROW (PortableGroup::NoFactory (factory_info.the_location,
type_id));
}
this->object_group_manager_._tao_add_member (
object_group,
factory_info.the_location,
member.in (),
type_id,
propagate_member_already_present
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
}
ACE_CATCHANY
{
// If the member reference is not nil, then the factory
// was successfully invoked. Since an exception was
// thrown, clean up the up created member.
if (!CORBA::is_nil (member.in ()))
{
factory_info.the_factory->delete_object (fcid.in ()
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
}
ACE_RE_THROW;
}
ACE_ENDTRY;
ACE_CHECK_RETURN (0);
return fcid._retn ();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -