summaryrefslogtreecommitdiff
path: root/trunk/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectReferenceFactory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectReferenceFactory.cpp')
-rw-r--r--trunk/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectReferenceFactory.cpp258
1 files changed, 258 insertions, 0 deletions
diff --git a/trunk/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectReferenceFactory.cpp b/trunk/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectReferenceFactory.cpp
new file mode 100644
index 00000000000..8898f4ff5c3
--- /dev/null
+++ b/trunk/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectReferenceFactory.cpp
@@ -0,0 +1,258 @@
+#include "orbsvcs/LoadBalancing/LB_ObjectReferenceFactory.h"
+
+ACE_RCSID (LoadBalancing,
+ LB_ObjectReferenceFactory,
+ "$Id$")
+
+#include "tao/debug.h"
+
+#include "ace/SString.h"
+#include "ace/OS_NS_strings.h"
+#include "ace/OS_NS_string.h"
+
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+// The number of different object groups to support.
+#ifndef TAO_LB_ORF_GROUP_TABLE_SIZE
+const size_t TAO_LB_ORF_GROUP_TABLE_SIZE = 16;
+#endif /* TAO_LB_ORF_GROUP_TABLE_SIZE */
+
+TAO_LB_ObjectReferenceFactory::TAO_LB_ObjectReferenceFactory (
+ PortableInterceptor::ObjectReferenceFactory * old_orf,
+ const CORBA::StringSeq & object_groups,
+ const CORBA::StringSeq & repository_ids,
+ const char * location,
+ CORBA::ORB_ptr orb,
+ CosLoadBalancing::LoadManager_ptr lm)
+ : old_orf_ (old_orf),
+ object_groups_ (object_groups),
+ repository_ids_ (repository_ids),
+ location_ (1),
+ table_ (TAO_LB_ORF_GROUP_TABLE_SIZE),
+ fcids_ (),
+ orb_ (CORBA::ORB::_duplicate (orb)),
+ lm_ (CosLoadBalancing::LoadManager::_duplicate (lm)),
+ registered_members_ (0)
+{
+ // Claim ownership of the old ObjectReferenceFactory.
+ CORBA::add_ref (old_orf);
+
+ this->location_.length (1);
+ this->location_[0].id = CORBA::string_dup (location);
+
+ CORBA::ULong const len = repository_ids.length ();
+ ACE_NEW (this->registered_members_,
+ CORBA::Boolean[len]);
+
+ ACE_ASSERT (this->registered_members_ != 0);
+ ACE_OS::memset (this->registered_members_,
+ 0,
+ len * sizeof (CORBA::Boolean));
+}
+
+TAO_LB_ObjectReferenceFactory::~TAO_LB_ObjectReferenceFactory (void)
+{
+ // No need to call CORBA::remove_ref() on this->old_orf_. It is a
+ // "_var" object, meaning that will be done automatically.
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+
+ if (!CORBA::is_nil (this->lm_.in ()))
+ {
+ const CORBA::ULong len = this->fcids_.size ();
+ for (CORBA::ULong i = 0; i < len; ++i)
+ {
+ ACE_TRY
+ {
+ // Clean up all object groups we created.
+ this->lm_->delete_object (this->fcids_[i].in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ // Ignore all exceptions.
+ }
+ ACE_ENDTRY;
+ }
+ }
+
+ // @todo De-register LoadAlert objects.
+ // @todo De-register object group members.
+
+ delete [] this->registered_members_;
+}
+
+CORBA::Object_ptr
+TAO_LB_ObjectReferenceFactory::make_object (
+ const char * repository_id,
+ const PortableInterceptor::ObjectId & id
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (repository_id == 0)
+ ACE_THROW_RETURN (CORBA::BAD_PARAM (), CORBA::Object::_nil ());
+
+ CORBA::Object_var obj =
+ this->old_orf_->make_object (repository_id,
+ id
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::Object::_nil ());
+
+ PortableGroup::ObjectGroup_var object_group;
+
+ CORBA::ULong index = 0;
+
+ CORBA::Boolean const found_group =
+ this->find_object_group (repository_id,
+ index,
+ object_group.out ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::Object::_nil ());
+
+ if (found_group)
+ {
+ // Be careful not to attempt duplicate registrations on
+ // subsequent object reference creation calls.
+ if (!this->registered_members_[index])
+ {
+ ACE_TRY
+ {
+ object_group =
+ this->lm_->add_member (object_group.in (),
+ this->location_,
+ obj.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (PortableGroup::ObjectGroupNotFound, ex)
+ {
+ if (TAO_debug_level > 0)
+ ACE_PRINT_EXCEPTION (ex,
+ "TAO_LB_ObjectReferenceFactory::"
+ "make_object");
+
+ ACE_THROW_RETURN (CORBA::BAD_PARAM (),
+ CORBA::Object::_nil ());
+ }
+ ACE_CATCH (PortableGroup::MemberAlreadyPresent, ex)
+ {
+ if (TAO_debug_level > 0)
+ ACE_PRINT_EXCEPTION (ex,
+ "TAO_LB_ObjectReferenceFactory::"
+ "make_object");
+
+ ACE_THROW_RETURN (CORBA::BAD_INV_ORDER (),
+ CORBA::Object::_nil ());
+
+ }
+ ACE_CATCH (PortableGroup::ObjectNotAdded, ex)
+ {
+ if (TAO_debug_level > 0)
+ ACE_PRINT_EXCEPTION (ex,
+ "TAO_LB_ObjectReferenceFactory::"
+ "make_object");
+
+ ACE_THROW_RETURN (CORBA::UNKNOWN (),
+ CORBA::Object::_nil ());
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (CORBA::Object::_nil ());
+
+ this->registered_members_[index] = 1;
+ }
+
+ // Return the object group reference instead.
+ return object_group._retn ();
+ }
+
+ // Not a load managed object. Simply return the object's actual
+ // object reference.
+ return obj._retn ();
+}
+
+CORBA::Boolean
+TAO_LB_ObjectReferenceFactory::find_object_group (
+ const char * repository_id,
+ CORBA::ULong & index,
+ PortableGroup::ObjectGroup_out object_group
+ ACE_ENV_ARG_DECL)
+{
+ if (!this->load_managed_object (repository_id, index))
+ return false;
+
+ PortableGroup::ObjectGroup_var group;
+ if (this->table_.find (repository_id, group) != 0)
+ {
+ if (ACE_OS::strcasecmp (this->object_groups_[index],
+ "CREATE") == 0)
+ {
+ PortableGroup::Criteria criteria (1);
+ criteria.length (1);
+
+ PortableGroup::Property & property = criteria[0];
+ property.nam.length (1);
+
+ property.nam[0].id =
+ CORBA::string_dup ("org.omg.PortableGroup.MembershipStyle");
+
+ // Configure for application-controlled membership.
+ PortableGroup::MembershipStyleValue msv =
+ PortableGroup::MEMB_APP_CTRL;
+ property.val <<= msv;
+
+ PortableGroup::GenericFactory::FactoryCreationId_var fcid;
+
+ group =
+ this->lm_->create_object (repository_id,
+ criteria,
+ fcid.out ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+
+ CORBA::ULong const len = this->fcids_.size ();
+ this->fcids_.size (len + 1); // Incremental growth. Yuck!
+ this->fcids_[len] = fcid;
+ }
+ else
+ {
+ group =
+ this->orb_->string_to_object (this->object_groups_[index]
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+ }
+
+ if (this->table_.bind (repository_id, group) != 0)
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ "TAO_LB_ObjectReferenceFactory::"
+ "find_object_group - "
+ "Couldn't bind object group reference.\n"));
+
+ ACE_THROW_RETURN (CORBA::INTERNAL (), 0);
+ }
+
+ object_group = group._retn ();
+ }
+
+ return 1;
+}
+
+CORBA::Boolean
+TAO_LB_ObjectReferenceFactory::load_managed_object (const char * repository_id,
+ CORBA::ULong & i)
+{
+ // @todo Make this more efficient.
+
+ CORBA::ULong const len = this->repository_ids_.length ();
+ for (i = 0; i < len; ++i)
+ if (ACE_OS::strcmp (this->repository_ids_[i], repository_id) == 0)
+ return true;
+
+ return false;
+}
+
+
+TAO_END_VERSIONED_NAMESPACE_DECL