load_balancer_i.cpp

来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 1,042 行 · 第 1/3 页

CPP
1,042
字号
// Load_Balancer_i.cpp,v 1.16 2003/02/21 01:32:34 ossama Exp
#include "Load_Balancer_i.h"
#include "ace/Auto_Ptr.h"
#include "ace/Hash_Map_Manager_T.h"

const char *rr_name_bind = "RR_Group";
// Name binding for the location of the Round Robin info in the mem pool

const char *random_name_bind = "Random_Group";
// Name binding for the location of the Random info in the mem pool

const char *flags_name_bind = "FLAGS";
// Name binding for the location of the flags info in the mem pool

const char *dll_name_bind = "DLL_LIST";
// Name binding for the DLL_LIst in the me_pool;

const char *server_id_name_bind = "server_id";
// Some cookie that is used for appending names

Object_Group_Factory_i::Object_Group_Factory_i (CORBA::ORB_ptr orb,
                                                PortableServer::POA_ptr poa)
  :orb_ (orb),
   poa_ (PortableServer::POA::_duplicate (poa)),
   random_groups_ (0),
   rr_groups_ (0),
   flags_ (0)
{
  ACE_MMAP_Memory_Pool::OPTIONS options (ACE_DEFAULT_BASE_ADDR);
  ACE_NEW (this->mem_pool_,
           ALLOCATOR ("Mem_Pool",
                      "Mem_Pool",
                      &options));
}

Object_Group_Factory_i::~Object_Group_Factory_i (void)
{
  delete this->mem_pool_;
}

PortableServer::POA_ptr
Object_Group_Factory_i::_default_POA (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
  ACE_THROW_SPEC ((CORBA::SystemException))
{
  return PortableServer::POA::_duplicate (this->poa_.in ());
}


Load_Balancer::Object_Group_ptr
Object_Group_Factory_i::make_round_robin (const char * id
                                          ACE_ENV_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException,
                     Load_Balancer::duplicate_group))
{

  if (this->mem_pool_->find (rr_name_bind,
                             (void *&)this->rr_groups_) == -1)
    {
      void *hash_map = this->mem_pool_->malloc (sizeof (HASH_MAP));
      ACE_NEW_THROW_EX (this->rr_groups_,
                        (hash_map) HASH_MAP (this->mem_pool_),
                        CORBA::NO_MEMORY ());
      ACE_CHECK_RETURN (Load_Balancer::Object_Group::_nil ());

      // Bind it in the mem pool with a name
      if (this->mem_pool_->bind (rr_name_bind,
                                 (void *)this->rr_groups_) != 0)
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             "Unable to bind \n"),
                            0);
        }
    }

  return this->make_group (0,
                           id
                           ACE_ENV_ARG_PARAMETER);
}

void
Object_Group_Factory_i::unbind_round_robin (const char * id
                                            ACE_ENV_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException,
                     Load_Balancer::no_such_group))
{
  if (this->rr_groups_ == 0)
    {
      if (this->mem_pool_->find (rr_name_bind,
                                 (void *&)this->rr_groups_) == -1)
        ACE_THROW (Load_Balancer::no_such_group ());
    }

  char *int_id = 0;

  // Throw an exception if not found in the HASH MAP
  if (this->rr_groups_->find (ACE_const_cast (char *, id),
                              this->mem_pool_) < 0)
    ACE_THROW (Load_Balancer::no_such_group ());

  // Unbind the entry
  this->rr_groups_->unbind (ACE_const_cast (char *, id),
                            int_id,
                            this->mem_pool_);

  // Free the memory from the pool
  this->mem_pool_->free (int_id - (ACE_OS::strlen (id) + 1));

  // Change the FLAGS variable
  if (this->flags_ == 0)
    {
      if (this->mem_pool_->find (flags_name_bind,
                                 (void *&)this->flags_) == -1)
        return;
    }

  // Bump down the flags value
  --this->flags_;

}

Load_Balancer::Object_Group_ptr
Object_Group_Factory_i::make_random (const char * id
                                     ACE_ENV_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException,
                     Load_Balancer::duplicate_group))
{

  if (this->mem_pool_->find (random_name_bind, (void * &)this->random_groups_) == -1)
    {
      void *hash_map = this->mem_pool_->malloc (sizeof (HASH_MAP));

      ACE_NEW_THROW_EX (this->random_groups_,
                        (hash_map) HASH_MAP (this->mem_pool_),
                        CORBA::NO_MEMORY ());
      ACE_CHECK_RETURN (Load_Balancer::Object_Group::_nil ());

      // Bind it in the mem pool with a name
      if (this->mem_pool_->bind (random_name_bind,
                                 (void *)this->random_groups_) != 0)
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             "Unable to bind \n"),
                            0);
        }
    }

  return this->make_group (1,
                           id
                           ACE_ENV_ARG_PARAMETER);
}


void
Object_Group_Factory_i::unbind_random (const char * id
                                       ACE_ENV_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException,
                     Load_Balancer::no_such_group))
{
  if (this->random_groups_ == 0)
    {
      if (this->mem_pool_->find (random_name_bind,
                                 (void *&)this->random_groups_) == -1)
        ACE_THROW (Load_Balancer::no_such_group ());
    }

  char *int_id = 0;

  // Throw an exception if not found in the HASH MAP
  if (this->random_groups_->find (ACE_const_cast (char *, id),
                                  this->mem_pool_) < 0)
    ACE_THROW (Load_Balancer::no_such_group ());

  // Unbind the entry
  this->random_groups_->unbind (ACE_const_cast (char *, id),
                                int_id,
                                this->mem_pool_);

  // Free the memory from the pool
  this->mem_pool_->free (int_id - (ACE_OS::strlen (id) + 1));

  // Change the FLAGS variable
  if (this->flags_ == 0)
    {
      if (this->mem_pool_->find (flags_name_bind,
                                 (void *&)this->flags_) == -1)
        return;
    }

  // Bump down the flags value
  this->flags_ -= 2;
}

Load_Balancer::Object_Group_ptr
Object_Group_Factory_i::make_group (int random,
                                    const char * id
                                    ACE_ENV_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException,
                     Load_Balancer::duplicate_group))
{
  // Store our result here for return.
  Load_Balancer::Object_Group_var group;

  // Create an appropriate servant.
  Object_Group_i *group_servant = 0;

  // Check to make sure we don't already have a group with the same
  // <id>.

  if (random)
    {
      if (this->random_groups_->find (ACE_const_cast (char *,id),
                                      this->mem_pool_) == 0)
        ACE_THROW_RETURN (Load_Balancer::duplicate_group (),
                          Load_Balancer::Object_Group::_nil ());
    }
  else
    {
      if (this->rr_groups_->find (ACE_const_cast (char *,id),
                                  this->mem_pool_) == 0)
        ACE_THROW_RETURN (Load_Balancer::duplicate_group (),
                          Load_Balancer::Object_Group::_nil ());
    }



  // As we are sure that it is not in the list go ahead and insert it
  if (random)
    ACE_NEW_THROW_EX (group_servant,
                      Random_Object_Group (id,
                                           this->poa_.in ()),
                      CORBA::NO_MEMORY ());
  else
    ACE_NEW_THROW_EX (group_servant,
                      RR_Object_Group (id,
                                       this->poa_.in ()),
                      CORBA::NO_MEMORY ());
  ACE_CHECK_RETURN (group._retn ());

  // Register with the poa, begin using ref. counting.
  group = group_servant->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
  ACE_CHECK_RETURN (group._retn ());

  group_servant->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
  ACE_CHECK_RETURN (Load_Balancer::Object_Group::_nil ());

  CORBA::String_var ior =
    this->orb_->object_to_string (group.in ()
                                  ACE_ENV_ARG_PARAMETER);
  ACE_CHECK_RETURN (Load_Balancer::Object_Group::_nil ());


  // Calculate and allocate the memory we need to store this name to
  // object binding.
  size_t id_len = ACE_OS::strlen (id) + 1;
  size_t kind_len = ACE_OS::strlen (ior.in ()) + 1;

  char *ptr = (char *) this->mem_pool_->malloc (id_len + kind_len);

  if (ptr == 0)
    ACE_THROW_RETURN (CORBA::NO_MEMORY (),
                      Load_Balancer::Object_Group::_nil ());

  char * id_ptr =  ptr;
  char * ior_ptr = ptr + id_len;

  ACE_OS::strcpy (id_ptr, id);
  ACE_OS::strcpy (ior_ptr, ior.in ());

  // Store the results here
  CORBA::Long result = 0;

  // Make an entry in appropriate map of groups.
  if (random)
    {
      result = this->random_groups_->bind (id_ptr,
                                           ior_ptr,
                                           this->mem_pool_);
    }
  else
    {
      result = this->rr_groups_->bind (id_ptr,
                                       ior_ptr,
                                       this->mem_pool_);
    }



  // Update the value of flags_
  this->update_flags (random
                      ACE_ENV_ARG_PARAMETER);
  ACE_CHECK_RETURN (Load_Balancer::Object_Group::_nil ());

  if (result == -1)
    {
      // For some reason the  bind failed. Free our
      // dynamically allocated  memory.
      this->mem_pool_->free ((void *) ptr);
      ACE_THROW_RETURN (Load_Balancer::duplicate_group (),
                        Load_Balancer::Object_Group::_nil ());

    }

  // Return.
  ACE_DEBUG ((LM_DEBUG, "Successfully created new group: %s\n", id));

  return group._retn ();
}


Load_Balancer::Object_Group_ptr
Object_Group_Factory_i::resolve (const char * id
                                 ACE_ENV_ARG_DECL)
    ACE_THROW_SPEC ((CORBA::SystemException,
                     Load_Balancer::no_such_group))
{



#if defined (DOORS_MEASURE_STATS)
  // Time the calls
  // Record the entry  time.
  ACE_hrtime_t latency_base = ACE_OS::gethrtime ();

#endif /*DOORS_MEASURE_STATS*/

  // It could be that the Load balancing service could have failed
  // before the Client tries to invoke this call.. In such a case the
  // Service should look in to the MMAP file and read in the info
  // before it can resolve the ID sent by the client.. So we check
  // whether the class holds the pointer.. If not we look in to the
  // MMAP file for the relevant info..
  if (!this->rr_groups_)
    {
      if (this->mem_pool_->find (rr_name_bind,
                                 (void *&)this->rr_groups_) == -1)
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             ACE_TEXT ("(%N|%l) The factory does not have any references "),
                             ACE_TEXT ("to the group that you have sought \n\n")),
                            0);
        }
    }

  if (!this->random_groups_)
    {
      if (this->mem_pool_->find (random_name_bind,
                                 (void *&)this->random_groups_) == -1)
        {

⌨️ 快捷键说明

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