summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/RTCosScheduling/RTCosScheduling_ClientScheduler_i.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/RTCosScheduling/RTCosScheduling_ClientScheduler_i.cpp')
-rw-r--r--TAO/orbsvcs/orbsvcs/RTCosScheduling/RTCosScheduling_ClientScheduler_i.cpp469
1 files changed, 469 insertions, 0 deletions
diff --git a/TAO/orbsvcs/orbsvcs/RTCosScheduling/RTCosScheduling_ClientScheduler_i.cpp b/TAO/orbsvcs/orbsvcs/RTCosScheduling/RTCosScheduling_ClientScheduler_i.cpp
new file mode 100644
index 00000000000..3eaf87a6c1f
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/RTCosScheduling/RTCosScheduling_ClientScheduler_i.cpp
@@ -0,0 +1,469 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file RTCosScheduling_ClientScheduler_i.cpp
+ *
+ * $Id$
+ *
+ * @author Matt Murphy <murphym@cs.uri.edu>
+ */
+//=============================================================================
+
+#include "orbsvcs/RTCosScheduling/RTCosScheduling_ClientScheduler_i.h"
+
+#include "ace/OS_NS_errno.h"
+#include "ace/OS_NS_stdio.h"
+
+#include "tao/ORB_Core.h"
+#include "tao/LocalObject.h"
+#include "tao/PortableInterceptorC.h"
+#include "tao/CodecFactory/CodecFactory.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+namespace TAO
+{
+
+ /// Constructor
+ RTCosScheduling_ClientScheduler_i::RTCosScheduling_ClientScheduler_i (
+ CORBA::ORB_var orb,
+ char *node_name,
+ char *file)
+ {
+ try
+ {
+ /// Read the resources and ceilings from the config file
+ /// and put them into the activity_map_
+ if ( !ACE_OS::strcmp(file,"") || file == NULL)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "No config supplied to the ServerScheduler, "
+ "Server will not scheudle object execution "
+ "(ServerScheduler interceptor not installed)"));
+ }
+ else if (!tasks(node_name, file, &activity_map_))
+ {
+ ACE_DEBUG((LM_DEBUG,"Invalid Filename given, aborting!\n"));
+ ACE_OS::exit(1);
+ }
+ // The tasks were successfully read in, create the client interceptor
+ else
+ {
+#if (TAO_HAS_INTERCEPTORS == 1)
+ ACE_NEW_THROW_EX (this->client_interceptor_,
+ RTCosScheduling_ClientScheduler_Interceptor(orb),
+ CORBA::NO_MEMORY());
+
+ TAO_ORB_Core *orb_core = orb->orb_core();
+
+ // @@ (OO) Why isn't an ORBInitializer being used to
+ // register the interceptor? In fact, all of the
+ // following code should be done in an
+ // ORBInitializer, except for the interceptor list
+ // iteration. That is already done by the ORB when
+ // using an ORBInitializer to register an
+ // interceptor.
+
+ /// First, get a list of all interceptors currently registered
+ TAO::ClientRequestInterceptor_List::TYPE &interceptors =
+ orb_core->client_request_interceptors();
+
+
+ /// Now check to see if the ServerScheduler Interceptor has already
+ /// been registered
+ u_int i;
+ u_int unregistered = 1;
+ for (i = 0; i < interceptors.size() && unregistered; ++i)
+ {
+ if (ACE_OS::strncmp(interceptors[i]->_interface_repository_id (),
+ this->client_interceptor_->_interface_repository_id(),
+ ACE_OS::strlen(
+ this->client_interceptor_->_interface_repository_id()-2))
+ == 0)
+ {
+ /// The interceptor is already registered,
+ /// don't try to register it again
+ unregistered = 0;
+ }
+ }
+
+ /// if the ServerScheduler Interceptor was not registered by
+ /// another POA then register it now
+ if (unregistered)
+ {
+ orb_core->add_interceptor(this->client_interceptor_);
+ }
+#endif /* TAO_HAS_INTERCEPTORS == 1 */
+
+ /// Now resolve a reference to the Real Time ORB
+ CORBA::Object_var rt_obj =
+ orb->resolve_initial_references("RTORB");
+
+ // Get a reference to the real time orb
+ RTCORBA::RTORB_var rt_orb =
+ RTCORBA::RTORB::_narrow (rt_obj.in ());
+
+ /// resolve a reference to RT Current
+ rt_obj =
+ orb->resolve_initial_references ("RTCurrent");
+
+ this->current_ =
+ RTCORBA::Current::_narrow (rt_obj.in ());
+
+ /// Resolve a reference to the Linear Priority Mapping Manager
+ rt_obj =
+ orb->resolve_initial_references("PriorityMappingManager");
+ RTCORBA::PriorityMappingManager_var mapping_manager =
+ RTCORBA::PriorityMappingManager::_narrow(rt_obj.in());
+
+ /// Create the Linear Priority Mapping Manager
+ ACE_NEW_THROW_EX(this->pm_,
+ TAO_Linear_Priority_Mapping(
+ ACE_SCHED_FIFO),
+ CORBA::NO_MEMORY());
+ // WHERE the parameter is one of SCHED_OTHER, SCHED_FIFO, or SCHED_RR
+
+ mapping_manager->mapping(this->pm_);
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ACE_ERROR((LM_ERROR, "Could not configure the orb"));
+ ACE_OS::exit(1);
+ }
+}
+
+
+/// Implementation skeleton destructor
+RTCosScheduling_ClientScheduler_i::~RTCosScheduling_ClientScheduler_i (void)
+{
+ delete this->pm_;
+#if (TAO_HAS_INTERCEPTORS == 1)
+ delete this->client_interceptor_;
+#endif /* TAO_HAS_INTERCEPTORS == 1 */
+}
+
+
+void RTCosScheduling_ClientScheduler_i::schedule_activity (
+ const char * activity_name)
+{
+ /// Look up the priority using the activity name in the activity map
+ COS_SCHEDULER_ACTIVITY_VALUE priority = 0;
+ CORBA::Short result =
+ this->activity_map_.find(activity_name,
+ priority);
+
+ /// If the activity/priority was found, set the current to the
+ /// appropriate priority.
+ if (result != -1)
+ {
+ this->current_->the_priority(priority);
+ }
+ /// If the activity was not found, throw an UnknownName exception.
+ else
+ {
+ throw RTCosScheduling::UnknownName();
+ }
+}
+
+
+int
+RTCosScheduling_ClientScheduler_i::tasks(
+ const char *node_name,
+ const char *file_name,
+ CosSchedulerActivityMap *activity_map)
+{
+ /// get the activity list just for the particular node
+ const unsigned int BUF_MAX = 256;
+
+ FILE *fp = ACE_OS::fopen(file_name, "r");
+ /// Make sure we can open the file
+ if (fp == NULL)
+ {
+ /// Error return of we cannot open the file.
+ ACE_ERROR_RETURN((LM_ERROR,
+ "Could not find the config file %s, aborting\n",
+ file_name),
+ 0);
+ }
+
+
+ char line[BUF_MAX], key[64];
+ ACE_OS::strsncpy(key, "Node ", sizeof(key));
+ ACE_OS::strcat(key, node_name);
+
+ /// Skip to the appropriate node
+#ifndef ACE_LACKS_CLEARERR
+ ACE_OS::clearerr(fp);
+#else
+# warning ACE_OS::clearerr() is unimplemented on this platform.
+# warning This code may not function properly.
+#endif /* !ACE_LACKS_CLEARERR */
+ do
+ {
+ ACE_OS::fgets(line, BUF_MAX, fp);
+ /// Make sure we did not hit the end of file
+ if (ACE_OS::last_error() == EOF)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "Node %s not found in config file\n",
+ node_name),
+ 0);
+ break;
+ }
+ }
+ while (ACE_OS::strncmp(line, key, ACE_OS::strlen(key)) != 0);
+
+ /// Skip to the appropriate task section of the node
+#ifndef ACE_LACKS_CLEARERR
+ ACE_OS::clearerr(fp);
+#else
+# warning ACE_OS::clearerr() is unimplemented on this platform.
+# warning This code may not function properly.
+#endif /* !ACE_LACKS_CLEARERR */
+ do
+ {
+ ACE_OS::fgets(line, BUF_MAX, fp);
+ /// Make sure we did not hit the end of file
+ if (ACE_OS::last_error() == EOF)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "Task list not found for node %s\n",
+ node_name),
+ 0);
+ break;
+ }
+ }
+ while (ACE_OS::strncmp(line, "Tasks:", ACE_OS::strlen("Tasks:")) != 0);
+
+ CORBA::Short done = 0;
+ COS_SCHEDULER_ACTIVITY_KEY name;
+ COS_SCHEDULER_ACTIVITY_VALUE priority = 0;
+ u_int delimiter;
+
+ /// read each activity/priority pair from the config file
+ while (!done)
+ {
+ /// get the activity name
+ ACE_OS::fgets(line, BUF_MAX, fp);
+
+ /// Make sure we did not hit the end of file
+ if (ACE_OS::last_error() == EOF)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "Task list not found for node %s\n",
+ node_name),
+ 0);
+ break;
+ }
+
+ /// check to make sure we have not reached the end of the list.
+ if (ACE_OS::strncmp(line, "END", ACE_OS::strlen("END")) != 0)
+ {
+ name = ACE_CString(line);
+ delimiter = name.find('\t');
+ char *p = ACE_OS::strchr(line, '\t');
+ if (p)
+ priority = ACE_OS::atoi(p);
+ if (priority == 0)
+ priority = RTCORBA::minPriority;
+ if (delimiter < name.length() && delimiter > 0)
+ {
+ activity_map->bind(name.substr(0, delimiter), priority);
+ }
+ else
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ "Error in reading activities from %s",
+ file_name),
+ 0);
+ }
+ }
+ else
+ {
+ done = 1;
+ }
+ }
+
+ return 1;
+}
+
+
+#if (TAO_HAS_INTERCEPTORS == 1)
+
+RTCosScheduling_ClientScheduler_Interceptor::RTCosScheduling_ClientScheduler_Interceptor() : name_("RTCosScheduling_Client_Interceptor")
+{
+ try
+ {
+ /// resolve a reference to RT Current
+ int argc = 0;
+ CORBA::ORB_var orb = CORBA::ORB_init (argc,
+ 0,
+ 0);
+ CORBA::Object_var obj =
+ orb->resolve_initial_references ("RTCurrent");
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_OS::exit(1);
+ }
+ else
+ {
+ this->current_ =
+ RTCORBA::Current::_narrow (obj.in ());
+ }
+
+ obj =
+ orb->resolve_initial_references("CodecFactory");
+
+ IOP::CodecFactory_var codec_factory;
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "Could not initialize client interceptor, aborting!\n"));
+ ACE_OS::exit(1);
+ }
+ else
+ {
+ codec_factory = IOP::CodecFactory::_narrow(obj.in());
+ }
+
+
+ IOP::Encoding encoding;
+ encoding.format = IOP::ENCODING_CDR_ENCAPS;
+ encoding.major_version = 1;
+ encoding.minor_version = 2;
+
+ this->codec_ = codec_factory->create_codec(encoding);
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception (
+ "There was an error constructing the "
+ "ClientScheduler Interceptor\n");
+ }
+}
+
+
+RTCosScheduling_ClientScheduler_Interceptor::RTCosScheduling_ClientScheduler_Interceptor(
+ const CORBA::ORB_var orb) : name_("RTCosScheduling_Client_Interceptor")
+{
+ try
+ {
+ /// resolve a reference to RT Current
+ CORBA::Object_var obj =
+ orb->resolve_initial_references ("RTCurrent");
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_OS::exit(1);
+ }
+ else
+ {
+ this->current_ =
+ RTCORBA::Current::_narrow (obj.in ());
+ }
+
+ obj =
+ orb->resolve_initial_references("CodecFactory");
+
+ // set up the codec factory to create the codec necessary to
+ // encode the octet stream for the service context
+ IOP::CodecFactory_var codec_factory;
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "Could not initialize client interceptor, aborting!\n"));
+ ACE_OS::exit(1);
+ }
+ else
+ {
+ codec_factory = IOP::CodecFactory::_narrow(obj.in());
+ }
+
+
+ IOP::Encoding encoding;
+ encoding.format = IOP::ENCODING_CDR_ENCAPS;
+ encoding.major_version = 1;
+ encoding.minor_version = 2;
+
+ // Create the codec
+ this->codec_ = codec_factory->create_codec(encoding);
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Error in creating Client Interceptor\n");
+ }
+}
+
+char *
+RTCosScheduling_ClientScheduler_Interceptor::name ()
+{
+return CORBA::string_dup(this->name_);
+}
+
+void
+RTCosScheduling_ClientScheduler_Interceptor::destroy ()
+{
+}
+
+void
+RTCosScheduling_ClientScheduler_Interceptor::send_request (
+ PortableInterceptor::ClientRequestInfo_ptr ri)
+{
+ try
+ {
+
+ // Get the Corba priority that the activity is currently running at
+ CORBA::Any the_priority_as_any;
+ the_priority_as_any <<=
+ this->current_->the_priority();
+
+ // Set up a service context to hold the priority
+ IOP::ServiceContext sc;
+ sc.context_id = IOP::RTCorbaPriority;
+
+ // Convert the priority to an octet stream
+ // (that is how service contexts send data)
+ sc.context_data =
+ reinterpret_cast<CORBA::OctetSeq &> (*this->codec_->encode (the_priority_as_any));
+
+ // add the service context
+ ri->add_request_service_context(sc, 0);
+
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("ERROR - in Client interceptor\n");
+ throw CORBA::INTERNAL ();
+ }
+}
+
+void
+RTCosScheduling_ClientScheduler_Interceptor::send_poll (
+ PortableInterceptor::ClientRequestInfo_ptr)
+{
+}
+
+void
+RTCosScheduling_ClientScheduler_Interceptor::receive_reply (
+ PortableInterceptor::ClientRequestInfo_ptr)
+{
+}
+
+void
+RTCosScheduling_ClientScheduler_Interceptor::receive_exception (
+ PortableInterceptor::ClientRequestInfo_ptr)
+{
+}
+
+void
+RTCosScheduling_ClientScheduler_Interceptor::receive_other (
+ PortableInterceptor::ClientRequestInfo_ptr)
+{
+}
+
+#endif /* TAO_HAS_INTERCEPTORS == 1 */
+
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL