summaryrefslogtreecommitdiff
path: root/trunk/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RoundRobin.cpp
blob: 9c56658d726c071b6a90215302e68f0fdcbb9b00 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// -*- C++ -*-

#include "orbsvcs/LoadBalancing/LB_RoundRobin.h"

#include "orbsvcs/PortableGroup/PG_conf.h"

#include "tao/debug.h"
#include "tao/ORB_Constants.h"

ACE_RCSID (LoadBalancing,
           LB_RoundRobin,
           "$Id$")

TAO_BEGIN_VERSIONED_NAMESPACE_DECL

TAO_LB_RoundRobin::TAO_LB_RoundRobin (PortableServer::POA_ptr poa)
  : poa_ (PortableServer::POA::_duplicate (poa)),
    lock_ (),
    location_index_map_ (TAO_PG_MAX_OBJECT_GROUPS)
{
}

TAO_LB_RoundRobin::~TAO_LB_RoundRobin (void)
{
}

char *
TAO_LB_RoundRobin::name (void)
{
  return CORBA::string_dup ("RoundRobin");
}

CosLoadBalancing::Properties *
TAO_LB_RoundRobin::get_properties (void)
{
  // There are no RoundRobin properties.  Return an empty property
  // list.

  CosLoadBalancing::Properties * props = 0;
  ACE_NEW_THROW_EX (props,
                    CosLoadBalancing::Properties,
                    CORBA::NO_MEMORY (
                      CORBA::SystemException::_tao_minor_code (
                        TAO::VMCID,
                        ENOMEM),
                      CORBA::COMPLETED_NO));

  return props;
}

void
TAO_LB_RoundRobin::push_loads (
    const PortableGroup::Location & /* the_location */,
    const CosLoadBalancing::LoadList & /* loads */)
{
  throw CosLoadBalancing::StrategyNotAdaptive ();
}

CosLoadBalancing::LoadList *
TAO_LB_RoundRobin::get_loads (CosLoadBalancing::LoadManager_ptr load_manager,
                              const PortableGroup::Location & the_location)
{
  if (CORBA::is_nil (load_manager))
    throw CORBA::BAD_PARAM ();

  return load_manager->get_loads (the_location);
}

CORBA::Object_ptr
TAO_LB_RoundRobin::next_member (
    PortableGroup::ObjectGroup_ptr object_group,
    CosLoadBalancing::LoadManager_ptr load_manager)
{
  if (CORBA::is_nil (load_manager))
    throw CORBA::BAD_PARAM ();

  const PortableGroup::ObjectGroupId id =
    load_manager->get_object_group_id (object_group);

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

  // Since this is "built-in" strategy, the LoadManager is collocated.
  // There is no need to release the lock during the following
  // invocation.
  //
  // There is a race condition here.  The
  PortableGroup::Locations_var locations =
    load_manager->locations_of_members (object_group);

  const CORBA::ULong len = locations->length ();

  if (len == 0)
    throw CORBA::TRANSIENT ();

  TAO_LB_Location_Index_Map::ENTRY * entry;
  if (this->location_index_map_.find (id, entry) == 0)
    {
      CORBA::ULong & i = entry->int_id_;

      if (len <= i)
        i = 0;  // Reset, i.e. wrap around

      // No need to release the lock since the LoadManager is
      // collocated.
      CORBA::Object_var member =
        load_manager->get_member_ref (object_group,
                                      locations[i]);

      // Increment index to point to next location.
      i++;

      return member._retn ();
    }

  // The first time through this method.  Set up for the next time
  // around, and return the object reference residing at the first
  // location in the "locations of members" sequence.

  // Note that it is safe to set the next_index below to 1 even if the
  // length of the sequence is 1 since the above code handles the
  // boundary case correctly by wrapping around.

  const CORBA::ULong index = 0;
  if (this->location_index_map_.bind (id, index + 1) != 0)
    throw CORBA::INTERNAL ();

  return load_manager->get_member_ref (object_group,
                                       locations[index]);
}

void
TAO_LB_RoundRobin::analyze_loads (
    PortableGroup::ObjectGroup_ptr /* object_group */,
    CosLoadBalancing::LoadManager_ptr /* load_manager */)
{
}

PortableServer::POA_ptr
TAO_LB_RoundRobin::_default_POA (void)
{
  return PortableServer::POA::_duplicate (this->poa_.in ());
}

TAO_END_VERSIONED_NAMESPACE_DECL