summaryrefslogtreecommitdiff
path: root/ACE/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Callbacks.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Callbacks.cpp')
-rw-r--r--ACE/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Callbacks.cpp353
1 files changed, 353 insertions, 0 deletions
diff --git a/ACE/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Callbacks.cpp b/ACE/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Callbacks.cpp
new file mode 100644
index 00000000000..e46044243e7
--- /dev/null
+++ b/ACE/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Callbacks.cpp
@@ -0,0 +1,353 @@
+// $Id$
+
+#include "orbsvcs/FaultTolerance/FT_Service_Callbacks.h"
+#include "orbsvcs/FaultTolerance/FT_ClientPolicy_i.h"
+
+#include "ace/OS_NS_sys_time.h"
+
+#include "tao/MProfile.h"
+#include "tao/Profile.h"
+#include "tao/Tagged_Components.h"
+#include "tao/Stub.h"
+#include "tao/Invocation_Utils.h"
+#include "tao/ORB_Core.h"
+#include "tao/Client_Strategy_Factory.h"
+#include "tao/CDR.h"
+#include "tao/SystemException.h"
+
+ACE_RCSID (FaultTolerance,
+ FT_Service_Callbacks,
+ "$Id$")
+
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_FT_Service_Callbacks::TAO_FT_Service_Callbacks (TAO_ORB_Core *orb_core)
+
+ : orb_core_ (orb_core),
+ profile_lock_ (0)
+{
+ this->profile_lock_ =
+ this->orb_core_->client_factory ()->create_profile_lock ();
+}
+
+TAO_FT_Service_Callbacks::~TAO_FT_Service_Callbacks (void)
+{
+ // Delete the memeory for the lock
+ delete this->profile_lock_;
+}
+
+CORBA::Boolean
+TAO_FT_Service_Callbacks::select_profile (const TAO_MProfile &mprofile,
+ TAO_Profile *&pfile)
+{
+ CORBA::ULong const sz = mprofile.size ();
+
+ // Iterate through the list in a circular fashion. Stop one before
+ // the list instead of trying the same thing again.
+ for (CORBA::ULong i = 0;
+ i != sz;
+ ++i)
+ {
+ const TAO_Profile *curr_pfile = mprofile.get_profile (i);
+
+ IOP::TaggedComponent tagged_component;
+ tagged_component.tag = IOP::TAG_FT_PRIMARY;
+
+ // Get the tagged component from the profile
+ const TAO_Tagged_Components &pfile_tagged =
+ curr_pfile->tagged_components ();
+
+ // Search for the TaggedComponent that we want
+ if (pfile_tagged.get_component (tagged_component) == 1)
+ {
+ // We have found a primary IOR
+ pfile = const_cast<TAO_Profile *>(curr_pfile);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+CORBA::Boolean
+TAO_FT_Service_Callbacks::object_is_nil (CORBA::Object_ptr obj)
+{
+ // Get the count
+ CORBA::ULong count = obj->_stubobj ()->base_profiles ().profile_count ();
+
+ // If the profile count is zero then return true
+ if (count == 0)
+ return true;
+ else
+ {
+ // else if each of the profile is nil
+ for (CORBA::ULong cnt = 0;
+ cnt < count;
+ cnt++)
+ {
+ TAO_Profile *pfile =
+ obj->_stubobj ()->base_profiles ().get_profile (cnt);
+
+ if (pfile != 0)
+ return false;
+ }
+ }
+
+ // If it reaches here then it should be nill
+ return true;
+
+}
+
+TAO_Service_Callbacks::Profile_Equivalence
+TAO_FT_Service_Callbacks::is_profile_equivalent (const TAO_Profile *this_p,
+ const TAO_Profile *that_p)
+{
+ const TAO_Tagged_Components &this_comp =
+ this_p->tagged_components ();
+
+ const TAO_Tagged_Components &that_comp =
+ that_p->tagged_components ();
+
+ IOP::TaggedComponent this_tc, that_tc;
+ this_tc.tag = that_tc.tag = IOP::TAG_FT_GROUP;
+
+ if (this_comp.get_component (this_tc) == 1)
+ {
+ if (that_comp.get_component (that_tc) == 1)
+ {
+ TAO_InputCDR this_cdr (reinterpret_cast<const char*> (this_tc.component_data.get_buffer ()),
+ this_tc.component_data.length ());
+
+ TAO_InputCDR that_cdr (reinterpret_cast<const char*> (that_tc.component_data.get_buffer ()),
+ that_tc.component_data.length ());
+
+ CORBA::Boolean this_byte_order;
+ CORBA::Boolean that_byte_order;
+
+ if (this_cdr >> ACE_InputCDR::to_boolean (this_byte_order) == 0 ||
+ that_cdr >> ACE_InputCDR::to_boolean (that_byte_order) == 0)
+ {
+ // Have tags but full of garbage - not equivalent
+ return TAO_Service_Callbacks::NOT_EQUIVALENT;
+ }
+
+ this_cdr.reset_byte_order (static_cast<int> (this_byte_order));
+ that_cdr.reset_byte_order (static_cast<int> (that_byte_order));
+
+
+ FT::TagFTGroupTaggedComponent this_group_component;
+ FT::TagFTGroupTaggedComponent that_group_component;
+
+ this_cdr >> this_group_component;
+ that_cdr >> that_group_component;
+
+ // check if domain id and group id are the same
+ if ((ACE_OS::strcmp (this_group_component.group_domain_id,
+ that_group_component.group_domain_id) == 0) &&
+ (this_group_component.object_group_id ==
+ that_group_component.object_group_id))
+ {
+ // Both have matching tags - true
+ return TAO_Service_Callbacks::EQUIVALENT;
+ }
+ }
+
+ return TAO_Service_Callbacks::NOT_EQUIVALENT;
+ }
+ else
+ {
+ if (that_comp.get_component (that_tc) == 1)
+ {
+ return TAO_Service_Callbacks::NOT_EQUIVALENT;
+ }
+ }
+
+ return TAO_Service_Callbacks::DONT_KNOW;
+}
+
+CORBA::ULong
+TAO_FT_Service_Callbacks::hash_ft (TAO_Profile *p, CORBA::ULong max)
+{
+ // At this point we assume that all the checks for other things
+ // within the profiles have been satisfied
+ TAO_Tagged_Components &this_comp =
+ p->tagged_components ();
+
+ IOP::TaggedComponent tc;
+ tc.tag = IOP::TAG_FT_GROUP;
+
+ if (this_comp.get_component (tc) == 0)
+ return 0;
+
+ // extract the group component
+ TAO_InputCDR cdr (reinterpret_cast<const char*> (tc.component_data.get_buffer ()),
+ tc.component_data.length ());
+
+ CORBA::Boolean byte_order;
+ if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
+ {
+ return 0;
+ }
+
+ cdr.reset_byte_order (static_cast<int> (byte_order));
+
+ FT::TagFTGroupTaggedComponent group_component;
+
+ cdr >> group_component;
+
+ return (CORBA::ULong) group_component.object_group_id % max;
+}
+
+CORBA::Boolean
+TAO_FT_Service_Callbacks::is_permanent_forward_condition (const CORBA::Object_ptr obj,
+ const TAO_Service_Context &service_context) const
+{
+ // do as much as possible outside of lock
+ IOP::ServiceContext sc;
+ sc.context_id = IOP::FT_GROUP_VERSION;
+
+ if (service_context.get_context (sc) == 0)
+ return false; /* false */
+
+ IOP::TaggedComponent tc;
+ tc.tag = IOP::TAG_FT_GROUP;
+
+ const TAO_Stub * stub = obj->_stubobj ();
+ // check for forward_profiles, branching to speed up operation on base_profiles
+ if (stub->forward_profiles ())
+ {
+ // set lock, as forward_profiles might be deleted concurrently
+ ACE_MT (ACE_GUARD_RETURN (ACE_Lock,
+ guard,
+ *stub->profile_lock (),
+ 0));
+
+ // even now, the forward profiles might have been deleted in the meanwhile
+ const TAO_MProfile &mprofile = stub->forward_profiles()
+ ? *(stub->forward_profiles())
+ : stub->base_profiles();
+
+ if (mprofile.profile_count() == 0)
+ // releasing lock
+ return false;
+
+ // assuming group-attributes are set for all profiles, check
+ // only the first profile
+ const TAO_Tagged_Components &tagged_components =
+ mprofile.get_profile (0)->tagged_components ();
+
+ if (tagged_components.get_component (tc) == 0)
+ // releasing lock
+ return false; /* false */
+
+ return true; /* true */
+
+ // releasing lock
+ }
+ else /* operate on constant basic_profiles */
+ {
+ const TAO_MProfile &mprofile = stub->base_profiles();
+
+ if (mprofile.profile_count() == 0)
+ return false;
+
+ // assuming group-attributes are set for all profiles, check only the first profile
+ const TAO_Tagged_Components &tagged_components =
+ mprofile.get_profile (0)->tagged_components ();
+
+ if (tagged_components.get_component (tc) == 0)
+ return false; /* false */
+
+ return true; /* true */
+ }
+}
+
+
+TAO::Invocation_Status
+TAO_FT_Service_Callbacks::raise_comm_failure (
+ IOP::ServiceContextList &context_list,
+ TAO_Profile *profile)
+{
+ if (this->restart_policy_check (context_list,
+ profile))
+ return TAO::TAO_INVOKE_RESTART;
+
+ // As the right tags are not found close the connection and throw an
+ // exception
+ throw CORBA::COMM_FAILURE (
+ CORBA::SystemException::_tao_minor_code (
+ TAO_INVOCATION_RECV_REQUEST_MINOR_CODE,
+ errno),
+ CORBA::COMPLETED_MAYBE);
+}
+
+TAO::Invocation_Status
+TAO_FT_Service_Callbacks::raise_transient_failure (
+ IOP::ServiceContextList &service,
+ TAO_Profile *profile)
+{
+ if (this->restart_policy_check (service,
+ profile))
+ return TAO::TAO_INVOKE_RESTART;
+
+ // Unlike COMM_FAILURE do not raise an exception since the
+ // completion status is not known and no assumption can be made.
+ return TAO::TAO_INVOKE_SYSTEM_EXCEPTION;
+}
+
+CORBA::Boolean
+TAO_FT_Service_Callbacks::restart_policy_check (
+ IOP::ServiceContextList &service_list,
+ const TAO_Profile *profile)
+{
+ // Check whether the IOP::FT_REQUEST exists within the service
+ // context list and FT::FT_GROUP exists within the profile that we
+ // have
+ IOP::TaggedComponent tagged_component;
+ tagged_component.tag = IOP::TAG_FT_GROUP;
+
+ if (profile->tagged_components ().get_component (tagged_component)
+ == 1)
+ {
+ // Look for the FT_REQUEST context id
+ for (CORBA::ULong i = 0;
+ i < service_list.length ();
+ i++)
+ {
+ if (service_list[i].context_id == IOP::FT_REQUEST)
+ {
+ // This would be a heck of a lot easier if we had the invocation
+ // here rather than just the contexts, but lemons -> lemonade I guess.
+ TAO_InputCDR cdr (reinterpret_cast <const char*> (service_list[i].context_data.get_buffer ()),
+ service_list[i].context_data.length ());
+ CORBA::Boolean byte_order;
+ if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
+ return 0;
+ cdr.reset_byte_order (static_cast <int> (byte_order));
+ FT::FTRequestServiceContext ftsrc;
+ if ((cdr >> ftsrc) == 0)
+ return 0;
+
+ return (ftsrc.expiration_time > now ());
+ }
+ }
+ }
+
+ // Failure
+ return 0;
+}
+
+TimeBase::TimeT
+TAO_FT_Service_Callbacks::now (void)
+{
+ // Grab the localtime on the machine where this is running
+ ACE_Time_Value time_val = ACE_OS::gettimeofday ();
+ TimeBase::TimeT sec_part = ((TimeBase::TimeT)time_val.sec ()) * 10000000;
+ TimeBase::TimeT usec_part = ((TimeBase::TimeT)time_val.usec ()) * 10;
+
+ // Add the offset to convert from posix time.
+ return (sec_part + usec_part + ACE_UINT64_LITERAL (0x1B21DD213814000));
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL