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

📄 pg_genericfactory.cpp

📁 这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用于网络游戏医学图像网关的高qos要求.更详细的内容可阅读相应的材料
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "PG_GenericFactory.h"
#include "PG_MemberInfo.h"
#include "PG_ObjectGroupManager.h"
#include "PG_PropertyManager.h"
#include "PG_Property_Utils.h"
#include "PG_conf.h"

#include "ace/OS_NS_stdio.h"

#include "tao/ORB_Constants.h"

ACE_RCSID (PortableGroup,
           PG_GenericFactory,
           "PG_GenericFactory.cpp,v 1.21 2003/12/22 01:44:38 wilson_d Exp")

TAO_PG_GenericFactory::TAO_PG_GenericFactory (
  TAO_PG_ObjectGroupManager & object_group_manager,
  TAO_PG_PropertyManager & property_manager)
  : poa_ (),
    object_group_manager_ (object_group_manager),
    property_manager_ (property_manager),
    factory_map_ (TAO_PG_MAX_OBJECT_GROUPS),
    next_fcid_ (0),
    lock_ ()
{
  this->object_group_manager_.generic_factory (this);
}

TAO_PG_GenericFactory::~TAO_PG_GenericFactory (void)
{
  ACE_DECLARE_NEW_CORBA_ENV;

  TAO_PG_Factory_Map::iterator end = this->factory_map_.end ();
  for (TAO_PG_Factory_Map::iterator i = this->factory_map_.begin ();
       i != end;
       ++i)
    {
      TAO_PG_Factory_Set & factory_set = (*i).int_id_;

      ACE_TRY
        {
          this->delete_object_i (factory_set,
                                 1 /* Ignore exceptions */
                                 ACE_ENV_ARG_PARAMETER);
          ACE_TRY_CHECK;
        }
      ACE_CATCHANY
        {
          // Ignore all exceptions.
        }
      ACE_ENDTRY;
    }

  (void) this->factory_map_.close ();
}

CORBA::Object_ptr
TAO_PG_GenericFactory::create_object (
    const char * type_id,
    const PortableGroup::Criteria & the_criteria,
    PortableGroup::GenericFactory::FactoryCreationId_out factory_creation_id
    ACE_ENV_ARG_DECL)
  ACE_THROW_SPEC ((CORBA::SystemException,
                   PortableGroup::NoFactory,
                   PortableGroup::ObjectNotCreated,
                   PortableGroup::InvalidCriteria,
                   PortableGroup::InvalidProperty,
                   PortableGroup::CannotMeetCriteria))
{
  PortableGroup::Properties_var properties =
    this->property_manager_.get_type_properties (type_id
                                                 ACE_ENV_ARG_PARAMETER);
  ACE_CHECK_RETURN (CORBA::Object::_nil ());

  PortableGroup::MembershipStyleValue membership_style =
    TAO_PG_MEMBERSHIP_STYLE;
  PortableGroup::FactoriesValue factory_infos(0);

  PortableGroup::InitialNumberMembersValue initial_number_members =
    TAO_PG_INITIAL_NUMBER_MEMBERS;
  PortableGroup::MinimumNumberMembersValue minimum_number_members =
    TAO_PG_MINIMUM_NUMBER_MEMBERS;

  // Make sure the criteria for the object group being created are
  // valid.
  this->process_criteria (type_id,
                          the_criteria,
                          membership_style,
                          factory_infos,
                          initial_number_members,
                          minimum_number_members
                          ACE_ENV_ARG_PARAMETER);
  ACE_CHECK_RETURN (CORBA::Object::_nil ());

  CORBA::ULong fcid = 0;

  {
    ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
                      guard,
                      this->lock_,
                      CORBA::Object::_nil ());

    // Start out with an initial value.
    fcid = this->next_fcid_;

    // Loop until a free FactoryCreationId is found, being careful to
    // search through the range of FactoryCreationIds only once.
    while (this->factory_map_.find (this->next_fcid_) == 0)
      {
        this->next_fcid_++;

        // If this is true, then no FactoryCreationIds are available.
        // This is highly unlikely since TAO implements a
        // FactoryCreationId as a 32 bit unsigned integer, meaning
        // that over 4 billion object groups are being managed by this
        // generic factory!
        if (this->next_fcid_ == fcid)
          ACE_THROW_RETURN (PortableGroup::ObjectNotCreated (),
                            CORBA::Object::_nil ());
      }

    // Just in case this->next_fcid_ was modified in the above search,
    // reassign the value.
    fcid = this->next_fcid_;
  }

  // The ObjectId for the newly created object group is comprised
  // solely of the FactoryCreationId.
  PortableServer::ObjectId_var oid;
  this->get_ObjectId (fcid, oid.out ());

  PortableGroup::ObjectGroup_var object_group =
    this->object_group_manager_.create_object_group (fcid,
                                                     oid.in (),
                                                     type_id,
                                                     the_criteria
                                                     ACE_ENV_ARG_PARAMETER);
  ACE_CHECK_RETURN (CORBA::Object::_nil ());

  TAO_PG_Factory_Set factory_set;

  const CORBA::ULong factory_infos_count = factory_infos.length ();

  ACE_TRY
    {
      if (factory_infos_count > 0
          && membership_style == PortableGroup::MEMB_INF_CTRL)
        {
          this->populate_object_group (object_group.in (),
                                       type_id,
                                       factory_infos,
                                       initial_number_members,
                                       factory_set
                                       ACE_ENV_ARG_PARAMETER);
          ACE_TRY_CHECK;

          if (this->factory_map_.bind (fcid, factory_set) != 0)
            ACE_TRY_THROW (PortableGroup::ObjectNotCreated ());

        }

      // Allocate a new FactoryCreationId for use as an "out" parameter.
      PortableGroup::GenericFactory::FactoryCreationId * tmp = 0;
      ACE_NEW_THROW_EX (tmp,
                        PortableGroup::GenericFactory::FactoryCreationId,
                        CORBA::NO_MEMORY (
                          CORBA::SystemException::_tao_minor_code (
                            TAO_DEFAULT_MINOR_CODE,
                            ENOMEM),
                          CORBA::COMPLETED_NO));
      ACE_CHECK_RETURN (CORBA::Object::_nil ());

      factory_creation_id = tmp;

      *tmp <<= fcid;
    }
  ACE_CATCHANY
    {
      this->delete_object_i (factory_set,
                             1 /* Ignore exceptions */
                             ACE_ENV_ARG_PARAMETER);
      ACE_TRY_CHECK;

      this->object_group_manager_.destroy_object_group (oid.in ()
                                                        ACE_ENV_ARG_PARAMETER);
      ACE_TRY_CHECK;

      ACE_RE_THROW;
    }
  ACE_ENDTRY;
  ACE_CHECK_RETURN (CORBA::Object::_nil ());

  {
    ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
                      guard,
                      this->lock_,
                      CORBA::Object::_nil ());

    // Object group was successfully created.  Increment the next
    // FactoryCreationId in preparation for the next object group.
    this->next_fcid_++;
  }

  return object_group._retn ();
}

void
TAO_PG_GenericFactory::delete_object (
    const PortableGroup::GenericFactory::FactoryCreationId &
      factory_creation_id
    ACE_ENV_ARG_DECL)
  ACE_THROW_SPEC ((CORBA::SystemException,
                   PortableGroup::ObjectNotFound))
{
  CORBA::ULong fcid = 0;

  if (factory_creation_id >>= fcid) // Extract the actual FactoryCreationId.
    {
      // Successfully extracted the FactoryCreationId.  Now find the
      // TAO_PG_Factory_Set corresponding to it.

      ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);

      // If no entry exists in the factory map, infrastructure
      // controlled membership was not used.
      TAO_PG_Factory_Map::ENTRY *entry = 0;
      if (this->factory_map_.find (fcid, entry) == 0)
        {
          TAO_PG_Factory_Set & factory_set = entry->int_id_;

          this->delete_object_i (factory_set,
                                 0  /* Do not ignore exceptions */
                                 ACE_ENV_ARG_PARAMETER);
          ACE_CHECK;

          if (this->factory_map_.unbind (fcid) != 0)
            ACE_THROW (CORBA::INTERNAL ());
        }
    }
  else
    ACE_THROW (PortableGroup::ObjectNotFound ());  // @@
                                                   //    CORBA::BAD_PARAM
                                                   //    instead?

  // The ObjectId for the newly created object group is comprised
  // solely of the FactoryCreationId.
  PortableServer::ObjectId_var oid;
  this->get_ObjectId (fcid, oid.out ());

  // Destroy the object group entry.
  this->object_group_manager_.destroy_object_group (
    oid.in ()
    ACE_ENV_ARG_PARAMETER);
  ACE_CHECK;
}

void
TAO_PG_GenericFactory::delete_object_i (TAO_PG_Factory_Set & factory_set,
                                        CORBA::Boolean ignore_exceptions
                                        ACE_ENV_ARG_DECL)
{
  const size_t len = factory_set.size ();

  size_t ilen = len;
  for (size_t i = 0; i != len; ++i)
    {
      // Destroy the object group member in reverse order in case the
      // array list is only partially destroyed and another call to
      // GenericFactory::delete_object() occurs afterwards.
      --ilen;

      TAO_PG_Factory_Node & factory_node = factory_set[ilen];

      PortableGroup::GenericFactory_ptr factory =
        factory_node.factory_info.the_factory.in ();
      const PortableGroup::GenericFactory::FactoryCreationId & member_fcid =
        factory_node.factory_creation_id.in ();

      ACE_TRY
        {
          factory->delete_object (member_fcid
                                  ACE_ENV_ARG_PARAMETER);
          ACE_TRY_CHECK;
        }
      ACE_CATCHANY
        {
          // Exceptions are generally only ignored when this
          // GenericFactory (not the one being invoked above) is
          // destroyed.  The idea is to allow the GenericFactory to be
          // destroyed regardless of whether or not all object group
          // members have been destroyed, and minimize the number of
          // object group members that have not been destroyed.
          if (!ignore_exceptions)
            ACE_RE_THROW;
        }
      ACE_ENDTRY;
      ACE_CHECK;

      // Since GenericFactory::delete_object() can throw an exception,
      // decrease the size of the factory array incrementally since
      // some object group members may not have been destroyed yet.
      // Note that this size reduction is fast since no memory is
      // actually deallocated.
      factory_set.size (ilen);
    }
}

void
TAO_PG_GenericFactory::delete_member (
  CORBA::ULong group_id,
  const PortableGroup::Location & location
  ACE_ENV_ARG_DECL)
{
  ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_);

  // If no entry exists in the factory map, infrastructure
  // controlled membership was not used.
  TAO_PG_Factory_Map::ENTRY *entry = 0;
  if (this->factory_map_.find (group_id, entry) == 0)
    {
      TAO_PG_Factory_Set & factory_set = entry->int_id_;

      const size_t len = factory_set.size ();

      // Iterate through the factory_set until a location match
      // occurs.  If a location match occurs, the member was created
      // by the infrastructure, i.e. this GenericFactory
      // implementation.  If no location matches, the member was
      // created by the application, and no operation will be
      // performed.
      //
      // @todo This is linear search.  Change to use a container with
      //       better search times.
      for (size_t i = 0; i < len; ++i)
        {
          TAO_PG_Factory_Node & node = factory_set[i];
          PortableGroup::FactoryInfo & info = node.factory_info;

          if (info.the_location == location)
            {
              info.the_factory->delete_object (node.factory_creation_id.in ()
                                               ACE_ENV_ARG_PARAMETER);
              ACE_CHECK;

              // The member has been successfully deleted.  Reduce the
              // size of the factory_set accordingly.
              if (len > 1)
                {
                  // Move the last element to the location of the
                  // current one and reduce the size of the set by
                  // one.
                  const size_t new_len = len - 1;
                  node = factory_set[new_len]; // Memberwise copy
                  factory_set.size (new_len);
                }
              else
                {
                  // A copy isn't necessary if the last member was
                  // deleted.
                  factory_set.size (0);
                }

              return;
            }
        }
    }
}

void
TAO_PG_GenericFactory::poa (PortableServer::POA_ptr p)
{
  ACE_ASSERT (CORBA::is_nil (this->poa_.in ())
              && !CORBA::is_nil (p));

  this->poa_ = PortableServer::POA::_duplicate (p);
}

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
  ACE_ENV_ARG_DECL)
{
  CORBA::ULong factory_infos_count = factory_infos.length ();
  factory_set.size (factory_infos_count);

  for (CORBA::ULong j = 0; j < factory_infos_count; ++j)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -