summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RoundRobin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RoundRobin.cpp')
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RoundRobin.cpp171
1 files changed, 171 insertions, 0 deletions
diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RoundRobin.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RoundRobin.cpp
new file mode 100644
index 00000000000..ab865f8020e
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_RoundRobin.cpp
@@ -0,0 +1,171 @@
+// -*- 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 (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ return CORBA::string_dup ("RoundRobin");
+}
+
+CosLoadBalancing::Properties *
+TAO_LB_RoundRobin::get_properties (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ // 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));
+ ACE_CHECK_RETURN (props);
+
+ return props;
+}
+
+void
+TAO_LB_RoundRobin::push_loads (
+ const PortableGroup::Location & /* the_location */,
+ const CosLoadBalancing::LoadList & /* loads */
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ CosLoadBalancing::StrategyNotAdaptive))
+{
+ ACE_THROW (CosLoadBalancing::StrategyNotAdaptive ());
+}
+
+CosLoadBalancing::LoadList *
+TAO_LB_RoundRobin::get_loads (CosLoadBalancing::LoadManager_ptr load_manager,
+ const PortableGroup::Location & the_location
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ CosLoadBalancing::LocationNotFound))
+{
+ if (CORBA::is_nil (load_manager))
+ ACE_THROW_RETURN (CORBA::BAD_PARAM (), 0);
+
+ return load_manager->get_loads (the_location
+ ACE_ENV_ARG_PARAMETER);
+}
+
+CORBA::Object_ptr
+TAO_LB_RoundRobin::next_member (
+ PortableGroup::ObjectGroup_ptr object_group,
+ CosLoadBalancing::LoadManager_ptr load_manager
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableGroup::ObjectGroupNotFound,
+ PortableGroup::MemberNotFound))
+{
+ if (CORBA::is_nil (load_manager))
+ ACE_THROW_RETURN (CORBA::BAD_PARAM (), CORBA::Object::_nil ());
+
+ const PortableGroup::ObjectGroupId id =
+ load_manager->get_object_group_id (object_group
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::Object::_nil ());
+
+ 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
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::Object::_nil ());
+
+ const CORBA::ULong len = locations->length ();
+
+ if (len == 0)
+ ACE_THROW_RETURN (CORBA::TRANSIENT (),
+ CORBA::Object::_nil ());
+
+ 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]
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::Object::_nil ());
+
+ // 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)
+ ACE_THROW_RETURN (CORBA::INTERNAL (), CORBA::Object::_nil ());
+
+ return load_manager->get_member_ref (object_group,
+ locations[index]
+ ACE_ENV_ARG_PARAMETER);
+}
+
+void
+TAO_LB_RoundRobin::analyze_loads (
+ PortableGroup::ObjectGroup_ptr /* object_group */,
+ CosLoadBalancing::LoadManager_ptr /* load_manager */
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+}
+
+PortableServer::POA_ptr
+TAO_LB_RoundRobin::_default_POA (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+{
+ return PortableServer::POA::_duplicate (this->poa_.in ());
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL