⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pg_genericfactory.cpp

📁 这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用于网络游戏医学图像网关的高qos要求.更详细的内容可阅读相应的材料
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    {
      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 + -