summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthrall <thrall@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2003-06-20 20:07:25 +0000
committerthrall <thrall@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2003-06-20 20:07:25 +0000
commitf1b7ed6a57f2ccbcf6cf8f122817b04b1c6199df (patch)
treec142c5bc22f73c490579ac270a06fe430809c774
parent71261c34a13b1107ca134eb97f3478cf97e4fbdf (diff)
downloadATCD-f1b7ed6a57f2ccbcf6cf8f122817b04b1c6199df.tar.gz
Initial commit of module. EC_Config is intended as a generic interface for configuring the EC and other communication channels (such as Distributable Threads). An abstract factory in the tradition of EC_Factory is provided for generating implementations behind the generic TestConfig interface. An application (Test.cpp) is provided which has partial implementation (Test_Handler.*) of using the ACEXML_Parser to automatically configure the EC from XML files (test.xml is an example, using the DTD file testconfig.dtd)
-rw-r--r--TAO/orbsvcs/tests/EC_Config/Config_Factory.cpp119
-rw-r--r--TAO/orbsvcs/tests/EC_Config/Config_Factory.h100
-rw-r--r--TAO/orbsvcs/tests/EC_Config/Consumer.cpp49
-rw-r--r--TAO/orbsvcs/tests/EC_Config/Consumer.h60
-rw-r--r--TAO/orbsvcs/tests/EC_Config/ECConfig.cpp501
-rw-r--r--TAO/orbsvcs/tests/EC_Config/ECConfig.h127
-rw-r--r--TAO/orbsvcs/tests/EC_Config/Makefile69
-rw-r--r--TAO/orbsvcs/tests/EC_Config/Schedule.h42
-rw-r--r--TAO/orbsvcs/tests/EC_Config/Service.cpp531
-rw-r--r--TAO/orbsvcs/tests/EC_Config/Supplier.cpp21
-rw-r--r--TAO/orbsvcs/tests/EC_Config/Supplier.h54
-rw-r--r--TAO/orbsvcs/tests/EC_Config/Test.cpp109
-rw-r--r--TAO/orbsvcs/tests/EC_Config/TestConfig.h125
-rw-r--r--TAO/orbsvcs/tests/EC_Config/Test_Handler.cpp204
-rw-r--r--TAO/orbsvcs/tests/EC_Config/Test_Handler.h168
-rw-r--r--TAO/orbsvcs/tests/EC_Config/svc.conf2
-rw-r--r--TAO/orbsvcs/tests/EC_Config/svc.conf.xml6
-rw-r--r--TAO/orbsvcs/tests/EC_Config/test.xml18
-rw-r--r--TAO/orbsvcs/tests/EC_Config/testconfig.dtd9
19 files changed, 2314 insertions, 0 deletions
diff --git a/TAO/orbsvcs/tests/EC_Config/Config_Factory.cpp b/TAO/orbsvcs/tests/EC_Config/Config_Factory.cpp
new file mode 100644
index 00000000000..d2712ef3daa
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/Config_Factory.cpp
@@ -0,0 +1,119 @@
+// $Id$
+
+#include "ace/Arg_Shifter.h"
+#include "orbsvcs/Sched/Reconfig_Scheduler.h"
+
+#include "Config_Factory.h"
+#include "ECConfig.h"
+
+using namespace ConfigFactory;
+
+//ACE_RCSID(DOA03, Default_Config_Factory, "$Id$")
+
+typedef TAO_Reconfig_Scheduler<TAO_MUF_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX> MUF_SCHED_TYPE;
+typedef TAO_Reconfig_Scheduler<TAO_RMS_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX> RMS_SCHED_TYPE;
+
+Default_Config_Factory::Default_Config_Factory (void)
+ : Config_Factory (),
+ test_config_(0) //default to ECConfig
+{
+}
+
+Default_Config_Factory::~Default_Config_Factory (void)
+{
+}
+
+int
+Default_Config_Factory::init_svcs (void)
+{
+ /*
+ return ACE_Service_Config::static_svcs ()->
+ insert (&ace_svc_desc_Default_Config_Factory);
+ */
+ return 0;
+}
+
+int
+Default_Config_Factory::init (int argc, ACE_TCHAR* argv[])
+{
+ ACE_Arg_Shifter arg_shifter (argc, argv);
+
+ while (arg_shifter.is_anything_left ())
+ {
+ const ACE_TCHAR *arg = arg_shifter.get_current ();
+
+ if (ACE_OS::strcasecmp (arg, ACE_LIB_TEXT("-ECConfig")) == 0)
+ {
+ arg_shifter.consume_arg ();
+ test_config_ = 0;
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ const ACE_TCHAR* opt = arg_shifter.get_current ();
+ if ((ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("null")) == 0)
+ || (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("rms")) == 0))
+ {
+ this->sched_type_ = RMS; //default
+ ACE_DEBUG ((LM_DEBUG,
+ "Default_Config_Factory: Scheduling type is RMS\n"));
+ }
+ else if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("muf")) == 0)
+ {
+ this->sched_type_ = MUF;
+ ACE_DEBUG ((LM_DEBUG,
+ "Default_Config_Factory: Scheduling type is MUF\n"));
+ }
+ else
+ ACE_ERROR ((LM_ERROR,
+ "Default_Config_Factory - "
+ "unsupported scheduling type <%s>\n",
+ opt));
+ arg_shifter.consume_arg ();
+ }
+ }
+ else
+ {
+ arg_shifter.consume_arg ();
+ ACE_DEBUG ((LM_DEBUG,
+ "Default_Config_Factory - "
+ "ignoring option <%s>\n",
+ arg));
+ }
+ }
+ return 0;
+}
+
+int
+Default_Config_Factory::fini (void)
+{
+ return 0;
+}
+
+TestConfig::Test_Config*
+Default_Config_Factory::create_testconfig ()
+{
+ if (this->test_config_ == 0)
+ {
+ switch (this->sched_type_) {
+ case MUF:
+ return new TestConfig::ECConfig<MUF_SCHED_TYPE>();
+ break;
+ case RMS:
+ return new TestConfig::ECConfig<RMS_SCHED_TYPE>();
+ break;
+ default:
+ ACE_ERROR ((LM_ERROR,
+ "Default_Config_Factory - "
+ "unknown scheduling type <%d>\n",
+ this->sched_type_));
+ return 0;
+ };
+ } //else...
+ return 0;
+}
+
+void
+Default_Config_Factory::destroy_testconfig (TestConfig::Test_Config *x)
+{
+ delete x;
+}
diff --git a/TAO/orbsvcs/tests/EC_Config/Config_Factory.h b/TAO/orbsvcs/tests/EC_Config/Config_Factory.h
new file mode 100644
index 00000000000..af65de85aac
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/Config_Factory.h
@@ -0,0 +1,100 @@
+/* -*- C++ -*- */
+// $Id$
+//
+// ============================================================================
+//
+// = FILENAME
+// Config_Factory
+//
+// = AUTHOR
+// Bryan Thrall (thrall@cse.wustl.edu)
+//
+// ============================================================================
+
+#ifndef CONFIGFACTORY_H
+#define CONFIGFACTORY_H
+
+#include "TestConfig.h"
+#include "ace/Service_Object.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+namespace ConfigFactory {
+
+/**
+ * @class Config_Factory
+ *
+ * @brief Abstract base factory for Test Configurators.
+ *
+ * Defines the Config_Factory interface.
+ *
+ * <H2>Memory Management</H2>
+ * The objects it creates are owned by this class, the client must
+ * invoke the corresponding destroy() method to release them.
+ */
+class Config_Factory : ACE_Service_Object
+{
+public:
+ virtual ~Config_Factory (void) {}
+
+ /// Create and destroy the TestConfig module.
+ virtual TestConfig::Test_Config* create_testconfig () = 0;
+ virtual void destroy_testconfig (TestConfig::Test_Config *) = 0;
+
+};
+
+/** Enumerates the different scheduling strategies certain
+ * Test_Configs generated by Config_Factories can use.
+ */
+enum Sched_Type {
+ RMS,
+ MUF,
+ EDF,
+ RMSMLF,
+ MIF
+};
+
+/**
+ * @class Default_Config_Factory
+ *
+ * @brief A generic factory for TestConfigs.
+ *
+ * This class allows the user to experiment with different TestConfig
+ * implementations. Using a command-line like interface the user
+ * can specify which strategies will this factory generate.
+ * Since the class can be dynamically loaded the strategies can be
+ * set in the service configurator file.
+ */
+class Default_Config_Factory : public Config_Factory
+{
+public:
+ /// Constructor
+ Default_Config_Factory (void);
+
+ /// destructor...
+ virtual ~Default_Config_Factory (void);
+
+ /// Helper function to register the default factory into the service
+ /// configurator.
+ static int init_svcs (void);
+
+ // = The Service_Object entry points
+ virtual int init (int argc, ACE_TCHAR* argv[]);
+ virtual int fini (void);
+
+ virtual TestConfig::Test_Config* create_testconfig ();
+
+ virtual void destroy_testconfig (TestConfig::Test_Config *);
+protected:
+ int test_config_;
+ Sched_Type sched_type_;
+};
+
+} /* namespace ConfigFactory */
+
+//ACE_STATIC_SVC_DECLARE (Default_Config_Factory)
+//ACE_FACTORY_DECLARE (TestConfig, Default_Config_Factory)
+
+#endif /* CONFIGFACTORY_H */
diff --git a/TAO/orbsvcs/tests/EC_Config/Consumer.cpp b/TAO/orbsvcs/tests/EC_Config/Consumer.cpp
new file mode 100644
index 00000000000..78d35d206de
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/Consumer.cpp
@@ -0,0 +1,49 @@
+// $Id$
+
+//#include "ace/Thread.h"
+#include "Consumer.h"
+
+ACE_RCSID(EC_Examples, Consumer, "$Id$")
+
+Consumer::Consumer (void)
+ : _ordinal(-1)
+{
+}
+
+Consumer::Consumer(int ord)
+ : _ordinal(ord)
+{
+}
+
+void
+Consumer::push (const RtecEventComm::EventSet& events
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (events.length () == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "Consumer (%P|%t) no events\n"));
+ return;
+ }
+
+ int prio = -1;
+ ACE_hthread_t handle;
+ ACE_Thread::self(handle);
+ ACE_Thread::getprio(handle,prio);
+ //ACE_thread_t tid = ACE_Thread::self();
+ ACE_DEBUG ((LM_DEBUG, "Consumer #%d @%d (%P|%t) we received event type %d\n",
+ _ordinal,prio,events[0].header.type));
+}
+
+void
+Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+}
+
+// ****************************************************************
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/TAO/orbsvcs/tests/EC_Config/Consumer.h b/TAO/orbsvcs/tests/EC_Config/Consumer.h
new file mode 100644
index 00000000000..d92e461fd20
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/Consumer.h
@@ -0,0 +1,60 @@
+/* -*- C++ -*- */
+// $Id$
+//
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS Real-time Event Channel examples
+//
+// = FILENAME
+// Consumer
+//
+// = AUTHOR
+// Carlos O'Ryan (coryan@cs.wustl.edu)
+//
+// ============================================================================
+
+#ifndef CONSUMER_H
+#define CONSUMER_H
+
+#include "orbsvcs/RtecEventCommS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class Consumer : public POA_RtecEventComm::PushConsumer
+{
+ // = TITLE
+ // Simple consumer object
+ //
+ // = DESCRIPTION
+ // This class is a consumer of events.
+ // It simply register for two event typesone event type
+ // The class is just a helper to simplify common tasks in EC
+ // tests, such as subscribing for a range of events, disconnecting
+ // from the EC, informing the driver of shutdown messages, etc.
+ //
+ // There are several ways to connect and disconnect this class,
+ // and it is up to the driver program to use the right one.
+ //
+public:
+ Consumer (void);
+ // Constructor
+
+ Consumer(int ord);
+
+ // = The RtecEventComm::PushConsumer methods
+
+ virtual void push (const RtecEventComm::EventSet& events
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ // The skeleton methods.
+
+private:
+ int _ordinal;
+};
+
+#endif /* CONSUMER_H */
diff --git a/TAO/orbsvcs/tests/EC_Config/ECConfig.cpp b/TAO/orbsvcs/tests/EC_Config/ECConfig.cpp
new file mode 100644
index 00000000000..9a0b356ebe9
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/ECConfig.cpp
@@ -0,0 +1,501 @@
+// $Id$
+
+#ifndef ECCONFIG_C
+#define ECCONFIG_C
+
+#include <sstream> //for ostringstream
+
+#include "ace/Array.h"
+#include "ace/Bound_Ptr.h"
+#include "orbsvcs/Scheduler_Factory.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Event_Service_Constants.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Kokyu_Factory.h"
+
+#include "ECConfig.h"
+
+namespace TestConfig {
+
+template <class SCHED_STRAT>
+ECConfig<SCHED_STRAT>::ECConfig (void)
+ : Test_Config (),
+ configured (false)
+{
+}
+
+template <class SCHED_STRAT>
+ECConfig<SCHED_STRAT>::~ECConfig (void)
+{
+ this->reset();
+}
+
+template <class SCHED_STRAT> void
+ECConfig<SCHED_STRAT>::reset (void)
+{
+ // We should do a lot of cleanup (disconnect from the EC,
+ // deactivate all the objects with the POA, etc.).
+
+ delete this->ec_impl;
+
+ delete this->sched_impl;
+
+ for(size_t i=0; i<consumers.size(); ++i) {
+ delete this->consumers[i];
+ }
+
+ for(size_t i=0; i<suppliers.size(); ++i) {
+ delete this->suppliers[i];
+ }
+
+ configured = false;
+}
+
+template <class SCHED_STRAT> int
+ECConfig<SCHED_STRAT>::configure (TCFG_SET_WPTR testconfigs)
+{
+ if (configured) {
+ this->reset(); //delete memory used by previous configuration
+ }
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ this->initEC();
+
+ ////////////////// EC ready; do config ////////////////////
+ size_t tsize = testconfigs->size();
+ supplier_cfgs.size(tsize);
+ consumer_cfgs.size(tsize);
+ testcfgs.size(tsize);
+ consumers.size(tsize);
+ suppliers.size(tsize);
+ for (size_t i=0; i<tsize; ++i)
+ {
+ //ACE_Weak_Bound_Ptr doesn't have operator*()! ??
+ //test_config_t *curcfg = (*testconfigs)[i];
+ test_config_t *curcfg = (*testconfigs.unsafe_get())[i];
+ testcfgs[i] = curcfg;
+
+ RtecScheduler::Criticality_t criticality;
+ switch (curcfg->criticality) {
+ case VERY_LOW_CRITICALITY :
+ criticality = RtecScheduler::VERY_LOW_CRITICALITY;
+ break;
+ case LOW_CRITICALITY :
+ criticality = RtecScheduler::LOW_CRITICALITY;
+ break;
+ case MEDIUM_CRITICALITY :
+ criticality = RtecScheduler::MEDIUM_CRITICALITY;
+ break;
+ case HIGH_CRITICALITY :
+ criticality = RtecScheduler::HIGH_CRITICALITY;
+ break;
+ case VERY_HIGH_CRITICALITY :
+ criticality = RtecScheduler::VERY_HIGH_CRITICALITY;
+ break;
+ }
+
+ RtecScheduler::Importance_t importance;
+ switch (curcfg->importance) {
+ case VERY_LOW_IMPORTANCE :
+ importance = RtecScheduler::VERY_LOW_IMPORTANCE;
+ break;
+ case LOW_IMPORTANCE :
+ importance = RtecScheduler::LOW_IMPORTANCE;
+ break;
+ case MEDIUM_IMPORTANCE :
+ importance = RtecScheduler::MEDIUM_IMPORTANCE;
+ break;
+ case HIGH_IMPORTANCE :
+ importance = RtecScheduler::HIGH_IMPORTANCE;
+ break;
+ case VERY_HIGH_IMPORTANCE :
+ importance = RtecScheduler::VERY_HIGH_IMPORTANCE;
+ break;
+ }
+
+ //create supplier RT_Info
+ std::ostringstream supp_entry_pt;
+ supp_entry_pt << "Supplier Event Class " << i; //unique RT_Info entry point
+ RtecScheduler::handle_t rt_info =
+ this->scheduler->create (supp_entry_pt.str().c_str() ACE_ENV_ARG_PARAMETER);
+ ACE_Time_Value tv (0, curcfg->period);
+ TimeBase::TimeT time;
+ ORBSVCS_Time::Time_Value_to_TimeT (time, tv);
+ this->scheduler->set (rt_info,
+ criticality,
+ time, time, time,
+ time,
+ importance,
+ time,
+ 0,
+ RtecScheduler::OPERATION
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (this->supplier_cfgs.set(rt_info,i) != 0) {
+ ACE_DEBUG((LM_DEBUG, "Could not set supplier RT_Info into config: %d of %d\n",
+ i,consumer_cfgs.max_size()));
+ return 1;
+ }
+
+ //create consumer RT_Info
+ std::ostringstream cons_entry_pt;
+ cons_entry_pt << "Consumer Event Class " << i; //unique RT_Info entry point
+ rt_info =
+ this->scheduler->create (cons_entry_pt.str().c_str() ACE_ENV_ARG_PARAMETER);
+ tv.set (0, curcfg->period);
+ ORBSVCS_Time::Time_Value_to_TimeT (time, tv);
+ this->scheduler->set (rt_info,
+ criticality,
+ time, time, time,
+ time,
+ importance,
+ time,
+ 0,
+ RtecScheduler::OPERATION
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (this->consumer_cfgs.set(rt_info,i) != 0) {
+ ACE_DEBUG((LM_DEBUG, "Could not set consumer RT_Info into config: %d of %d\n",
+ i,consumer_cfgs.max_size()));
+ return 1;
+ }
+ }
+
+ this->connectConsumers();
+ this->connectSuppliers();
+
+ ACE_DEBUG ((LM_DEBUG, "Consumer RT_Infos:\n"));
+ print_RT_Infos (this->consumer_cfgs);
+ ACE_DEBUG ((LM_DEBUG, "\nSupplier RT_Infos:\n"));
+ print_RT_Infos (this->supplier_cfgs);
+
+ ////////////////// Configured; compute schedule ///////////
+ ACE_DEBUG ((LM_DEBUG, "Computing schedule\n"));
+ RtecScheduler::RT_Info_Set_var infos;
+ RtecScheduler::Config_Info_Set_var configs;
+ RtecScheduler::Scheduling_Anomaly_Set_var anomalies;
+
+ // Obtain the range of valid priorities in the current
+ // platform, the scheduler hard-code this values in the
+ // generated file, but in the future we may just use the
+ // "logical" priorities and define the mapping to OS
+ // priorities at run-time.
+ int min_os_priority =
+ ACE_Sched_Params::priority_min (ACE_SCHED_FIFO,
+ ACE_SCOPE_THREAD);
+ int max_os_priority =
+ ACE_Sched_Params::priority_max (ACE_SCHED_FIFO,
+ ACE_SCOPE_THREAD);
+ this->scheduler->compute_scheduling (min_os_priority,
+ max_os_priority,
+ infos.out (),
+ configs.out (),
+ anomalies.out ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Dump the schedule to a file..
+ ACE_Scheduler_Factory::dump_schedule (infos.in (),
+ configs.in (),
+ anomalies.in (),
+ "ecconfig.out");
+
+ ///////////// Activate the EC /////////////////
+ ACE_DEBUG ((LM_DEBUG, "activating EC\n"));
+ this->ec_impl->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ ACE_DEBUG ((LM_DEBUG, "EC activated\n"));
+
+ configured = true;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ECConfig");
+ return 1;
+ }
+ ACE_ENDTRY;
+ return 0; //successful config
+}
+
+template <class SCHED_STRAT> int
+ECConfig<SCHED_STRAT>::run (void)
+{
+ ACE_DEBUG ((LM_DEBUG, "Running ECConfig\n"));
+ if (!this->configured) {
+ ACE_DEBUG ((LM_DEBUG, "Tried to run before configured\n"));
+ return 1;
+ }
+
+ ACE_TRY
+ {
+ RtecEventComm::EventSet event (1);
+ event.length (1);
+
+ ACE_Array<int> evt_counts(this->testcfgs.size());
+ for(size_t i=0; i<this->testcfgs.size(); ++i)
+ {
+ //copy over total number of events per test_config_t to send
+ evt_counts[i] = this->testcfgs[i]->num_entities;
+ }
+
+ size_t num_done = 0; //total number of testcfgs which have no more events to push
+ while (num_done<this->testcfgs.size())
+ {
+ //for each consumer, push an event
+ for(size_t i=0; i<this->testcfgs.size() && i<this->consumer_proxys.size(); ++i)
+ {
+ if (evt_counts[i]<=0)
+ {
+ if (evt_counts[i]==0)
+ {
+ //just finished
+ ++num_done;
+ evt_counts[i]--; //indicate accounted for in num_done
+ } //else already incr num_done for this one
+ continue; //no more events of this to push
+ } //else...
+ test_config_t *tcfg = this->testcfgs[i];
+ ProxyList::TYPE curproxy = this->consumer_proxys[i];
+
+ event[0].header.type = ACE_ES_EVENT_UNDEFINED+tcfg->type;
+ event[0].header.source = supplier_ids[i];
+ event[0].header.ttl = 1;
+
+ curproxy->push (event ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ //event pushed, so decr corresponding evt_count
+ evt_counts[i]--;
+
+ // BT TODO sleep until next period expires
+ ACE_Time_Value rate (0, 10000);
+ ACE_OS::sleep (rate);
+
+ }
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ECConfig");
+ return 1;
+ }
+ ACE_ENDTRY;
+
+ return 0; //successful run
+}
+
+template <class SCHED_STRAT> int
+ECConfig<SCHED_STRAT>::initEC()
+{
+ TAO_EC_Kokyu_Factory::init_svcs ();
+
+ ACE_DEBUG ((LM_DEBUG, "Initializing event channel\n"));
+ ACE_TRY
+ {
+ // ORB initialization boiler plate...
+ int argc = 0;
+ char** argv = 0;
+ this->orb =
+ CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::Object_var object =
+ orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ this->poa =
+ PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ this->poa_manager =
+ poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ // DO these need to remain in scope beyond this function?
+
+ // Create a scheduling service
+ ACE_NEW_RETURN (this->sched_impl,SCHED_STRAT,1);
+
+ this->scheduler = sched_impl->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Create an event channel implementation...
+ TAO_EC_Event_Channel_Attributes attributes (poa.in (),
+ poa.in ());
+ attributes.scheduler = scheduler.in (); // no need to dup
+
+ ACE_NEW_RETURN (this->ec_impl,TAO_EC_Event_Channel (attributes),1);
+
+ this->event_channel =
+ this->ec_impl->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ECConfig");
+ return 1;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+template <class SCHED_STRAT> int
+ECConfig<SCHED_STRAT>::connectConsumers()
+{
+ ACE_TRY
+ {
+ // The canonical protocol to connect to the EC
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ this->event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG, "connecting consumers\n"));
+ for (size_t i=0; i<this->consumer_cfgs.size() && i<this->testcfgs.size(); ++i)
+ {
+ ACE_NEW_RETURN(this->consumers[i],Consumer(i),1);
+
+ RtecScheduler::handle_t hndl = this->consumer_cfgs[i];
+ test_config_t *tcfg = this->testcfgs[i];
+
+ ACE_ConsumerQOS_Factory consumer_qos;
+ //consumer_qos.start_disjunction_group ();
+ // The types in the range [0,ACE_ES_EVENT_UNDEFINED) are
+ // reserved for the EC...
+ consumer_qos.insert_type (ACE_ES_EVENT_UNDEFINED+tcfg->type,
+ hndl);
+
+ RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy =
+ consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventComm::PushConsumer_var consumerv =
+ consumers[i]->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ supplier_proxy->connect_push_consumer (consumerv.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ECConfig");
+ return 1;
+ }
+ ACE_ENDTRY;
+
+ return 0; //successful run
+}
+
+template <class SCHED_STRAT> int
+ECConfig<SCHED_STRAT>::connectSuppliers()
+{
+ ACE_TRY
+ {
+ // The canonical protocol to connect to the EC
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG, "connecting suppliers\n"));
+ supplier_ids.size(supplier_cfgs.size());
+ consumer_proxys.size(supplier_cfgs.size());
+ for (size_t i=0; i<supplier_cfgs.size() && i<this->testcfgs.size(); ++i)
+ {
+ ACE_NEW_RETURN(this->suppliers[i],Supplier(),1);
+
+ RtecScheduler::handle_t hndl = this->supplier_cfgs[i];
+ test_config_t *tcfg = this->testcfgs[i];
+
+ RtecEventComm::EventSourceID supplier_id = i;
+ this->supplier_ids[i] = supplier_id;
+
+ ACE_SupplierQOS_Factory supplier_qos;
+ supplier_qos.insert (supplier_id,
+ ACE_ES_EVENT_UNDEFINED+tcfg->type,
+ hndl,
+ 1); // number of calls, but what does that mean?
+
+ consumer_proxys[i] =
+ supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventComm::PushSupplier_var supplier =
+ suppliers[i]->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ //PROBLEM: Occasional segfault here:
+ consumer_proxys[i]->connect_push_supplier (supplier.in (),
+ supplier_qos.get_SupplierQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ ACE_DEBUG ((LM_DEBUG, "suppliers connected\n"));
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ECConfig");
+ return 1;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+template <class SCHED_STRAT> void
+ECConfig<SCHED_STRAT>::print_RT_Infos (ACE_Array<RtecScheduler::handle_t> cfg_set)
+{
+ char *rt_info_format = "{%20s, %10d, %10d, %10d, "
+ "%10d, %10d, "
+ "(RtecScheduler::Criticality_t) %d, "
+ "(RtecScheduler::Importance_t) %d, "
+ "%10d, %10d, %10d, %10d, %10d, "
+ "(RtecScheduler::Info_Type_t) %d }";
+ ACE_TRY
+ {
+ for (size_t i=0; i<cfg_set.size(); ++i) {
+ RtecScheduler::handle_t hndl = cfg_set[i];
+ RtecScheduler::RT_Info info = *(this->scheduler->get(hndl));
+ ACE_TRY_CHECK;
+
+ if (i!=0)
+ {
+ //finish previous line
+ ACE_DEBUG ((LM_DEBUG, "\n"));
+ }
+ ACE_DEBUG ((LM_DEBUG, rt_info_format,
+ (const char *) info.entry_point,
+ info.handle,
+ ACE_CU64_TO_CU32 (info.worst_case_execution_time),
+ ACE_CU64_TO_CU32 (info.typical_execution_time),
+ ACE_CU64_TO_CU32 (info.cached_execution_time),
+ info.period,
+ info.criticality,
+ info.importance,
+ ACE_CU64_TO_CU32 (info.quantum),
+ info.threads,
+ info.priority,
+ info.preemption_subpriority,
+ info.preemption_priority,
+ info.info_type));
+ }
+ //finish last line
+ ACE_DEBUG ((LM_DEBUG, "\n"));
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ECConfig");
+ }
+ ACE_ENDTRY;
+
+}
+
+} /* namespace TestConfig */
+
+#endif /* ECCONFIG_C */
diff --git a/TAO/orbsvcs/tests/EC_Config/ECConfig.h b/TAO/orbsvcs/tests/EC_Config/ECConfig.h
new file mode 100644
index 00000000000..365943b7bcb
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/ECConfig.h
@@ -0,0 +1,127 @@
+/* -*- C++ -*- */
+// $Id$
+//
+// ============================================================================
+//
+// = FILENAME
+// ECConfig
+//
+// = AUTHOR
+// Bryan Thrall (thrall@cse.wustl.edu)
+//
+// ============================================================================
+
+#ifndef ECCONFIG_H
+#define ECCONFIG_H
+
+#include "ace/Array.h"
+#include "ace/Synch.h"
+#include "orbsvcs/RtecSchedulerS.h" //for POA_RtecScheduler
+#include "orbsvcs/RtecSchedulerC.h"
+#include "orbsvcs/RtecEventChannelAdminC.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+
+#include "TestConfig.h"
+#include "Consumer.h"
+#include "Supplier.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+namespace TestConfig {
+
+typedef ACE_Array<RtecEventChannelAdmin::ProxyPushConsumer_var> ProxyList;
+typedef ACE_Array<RtecScheduler::handle_t> ConfigList;
+typedef ACE_Array<RtecEventComm::EventSourceID> SupplierIDList;
+
+typedef ACE_Array<Consumer*> ConsumerList;
+typedef ACE_Array<Supplier*> SupplierList;
+
+template <class SCHED_STRAT>
+class ECConfig : public Test_Config {
+public:
+ ECConfig (void);
+
+ virtual ~ECConfig (void);
+
+ virtual int configure (TCFG_SET_WPTR configs);
+ //does not take ownership of the Test_Config_Set but
+ //needs to use the test_config_t in that set until
+ //the ECConfig goes out of scope
+
+ virtual int run (void);
+ //If we try to distinguish between final-push and final-receipt,
+ //that might be tracked in the Consumer (which would be easy as long
+ //as filtering and correlation isn't used -- in that case, there
+ //might be more than one receiver of an event, so you might get
+ //multiple receipt-notices). There could also be a race-condition
+ //problem between the various threads when reporting the receipt of
+ //events.
+
+protected:
+ virtual int initEC (void);
+
+ virtual int connectConsumers (void);
+
+ virtual int connectSuppliers (void);
+
+ virtual void reset (void);
+ //
+
+private:
+
+ void print_RT_Infos (ACE_Array<RtecScheduler::handle_t> cfg_set);
+
+ Test_Config_Set testcfgs;
+ //copy of the currently configured Test_Config_Set
+ //using the same test_config_t objects
+
+ CORBA::ORB_var orb;
+
+ PortableServer::POA_var poa;
+
+ PortableServer::POAManager_var poa_manager;
+
+ RtecEventChannelAdmin::EventChannel_var event_channel;
+
+ RtecScheduler::Scheduler_var scheduler;
+ /*
+ ACE_Strong_Bound_Ptr<TAO_EC_Event_Channel,ACE_Null_Mutex> ec_impl;
+
+ ACE_Strong_Bound_Ptr<POA_RtecScheduler::Scheduler,ACE_Null_Mutex> sched_impl;
+ */
+ TAO_EC_Event_Channel *ec_impl;
+
+ POA_RtecScheduler::Scheduler *sched_impl;
+
+ ProxyList consumer_proxys;
+ //proxy objects for pushing events to consumers
+
+ ConfigList supplier_cfgs;
+ //RT_Infos generated by configure() for suppliers.
+
+ ConfigList consumer_cfgs;
+ //RT_Infos generated by configure() for consumers.
+
+ SupplierIDList supplier_ids;
+ //IDs of the suppliers
+
+ ConsumerList consumers;
+
+ SupplierList suppliers;
+
+ bool configured;
+};
+
+} /* namespace TestConfig */
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "ECConfig.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("ECConfig.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#endif /* ECCONFIG_H */
diff --git a/TAO/orbsvcs/tests/EC_Config/Makefile b/TAO/orbsvcs/tests/EC_Config/Makefile
new file mode 100644
index 00000000000..9bf027a7b07
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/Makefile
@@ -0,0 +1,69 @@
+#----------------------------------------------------------------------------
+#
+# $Id$
+#
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# Local macros
+#----------------------------------------------------------------------------
+
+ifndef TAO_ROOT
+ TAO_ROOT = $(ACE_ROOT)/TAO
+endif # ! TAO_ROOT
+
+BIN2 = Test
+
+#### If the orbsvcs library wasn't built with all components, don't
+#### try to build certain tests.
+TAO_ORBSVCS := $(shell sh $(ACE_ROOT)/bin/ace_components --orbsvcs)
+ifeq (Event,$(findstring Event,$(TAO_ORBSVCS)))
+ ifeq (Sched,$(findstring Sched,$(TAO_ORBSVCS)))
+ BIN = $(BIN2)
+ endif # Sched
+endif # Event
+
+PSRC= Test.cpp Supplier.cpp Consumer.cpp ECConfig.cpp Service.cpp Config_Factory.cpp Test_Handler.cpp
+LDLIBS = -lTAO_RTOLDEvent -lTAO_RTEvent -lTAO_RTSched -lTAO_CosNaming -lTAO_Svc_Utils -lTAO_IORTable -lTAO_Messaging -lTAO_PortableServer -lTAO -lTAO_RTKokyuEvent -lACEXML_Parser
+
+# The complete path to orbsvcs/orbsvcs/Sched is required for DU/CXX
+# automatic template instantiation magic.
+CPPFLAGS += -I$(TAO_ROOT) -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_ROOT)/orbsvcs/orbsvcs/Sched \
+ $(foreach svc, $(TAO_ORBSVCS), -DTAO_ORBSVCS_HAS_$(svc))
+
+Test_OBJS=$(addsuffix .o, Test Supplier Consumer ECConfig Config_Factory Test_Handler)
+Service_OBJS=$(addsuffix .o, Service Supplier Consumer ECConfig)
+
+#----------------------------------------------------------------------------
+# Include macros and targets
+#----------------------------------------------------------------------------
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(TAO_ROOT)/rules.tao.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
+
+# To build multiple executables in the same directory on AIX, it works
+# best to wipe out any previously-created tempinc directory.
+# The compiler/linker isn't too smart about instantiating templates...
+ifdef TEMPINCDIR
+COMPILE.cc := $(RM) -rf tempinc; $(COMPILE.cc)
+endif
+
+#----------------------------------------------------------------------------
+# Local targets
+#----------------------------------------------------------------------------
+
+Test: $(addprefix $(VDIR),$(Test_OBJS))
+ $(LINK.cc) $(LDFLAGS) -o $@ $^ $(VLDLIBS) $(POSTLINK)
+
+Service: $(addprefix $(VDIR),$(Service_OBJS))
+ $(LINK.cc) $(LDFLAGS) -o $@ $^ $(VLDLIBS) $(POSTLINK)
+
+#----------------------------------------------------------------------------
+# Dependencies
+#----------------------------------------------------------------------------
+# DO NOT DELETE THIS LINE -- g++dep uses it.
diff --git a/TAO/orbsvcs/tests/EC_Config/Schedule.h b/TAO/orbsvcs/tests/EC_Config/Schedule.h
new file mode 100644
index 00000000000..55fab809258
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/Schedule.h
@@ -0,0 +1,42 @@
+// $Id$
+
+// This file was automatically generated by the Scheduler_Factory.
+// Before editing the file please consider generating it again.
+
+#include "orbsvcs/Scheduler_Factory.h"
+
+
+// There were no scheduling anomalies.
+
+
+static ACE_Scheduler_Factory::POD_RT_Info infos[] = {
+{"Dispatching_Task-250000.us", 1, 0, 0, 0, 250000, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 1, 58, 4, 1, (RtecScheduler::Info_Type_t) 0 },
+{"Dispatching_Task-500000.us", 2, 0, 0, 0, 500000, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 1, 58, 5, 1, (RtecScheduler::Info_Type_t) 0 },
+{"Dispatching_Task-1000000.us", 3, 0, 0, 0, 1000000, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 1, 58, 6, 1, (RtecScheduler::Info_Type_t) 0 },
+{"Dispatching_Task-2000000.us", 4, 0, 0, 0, 2000000, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 1, 58, 7, 1, (RtecScheduler::Info_Type_t) 0 },
+{"Dispatching_Task-10000000.us", 5, 0, 0, 0, 10000000, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 1, 58, 8, 1, (RtecScheduler::Info_Type_t) 0 },
+{ "consumer_event_1", 6, 20000, 20000, 20000, 0, (RtecScheduler::Criticality_t) 4, (RtecScheduler::Importance_t) 0, 20000, 0, 59, 0, 0, (RtecScheduler::Info_Type_t) 0 },
+{ "consumer_event_2", 7, 10000, 10000, 10000, 0, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 10000, 0, 58, 1, 1, (RtecScheduler::Info_Type_t) 0 },
+{"(consumer_event_1#rep||consumer_event_2#rep)", 8, 0, 0, 0, 0, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 0, 58, 3, 1, (RtecScheduler::Info_Type_t) 2 },
+{"consumer_event_1#rep", 9, 0, 0, 0, 0, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 0, 58, 0, 1, (RtecScheduler::Info_Type_t) 0 },
+{"consumer_event_2#rep", 10, 0, 0, 0, 0, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 0, 58, 2, 1, (RtecScheduler::Info_Type_t) 0 },
+{ "supplier_event_1", 11, 0, 0, 0, 100000, (RtecScheduler::Criticality_t) 4, (RtecScheduler::Importance_t) 0, 0, 1, 59, 1, 0, (RtecScheduler::Info_Type_t) 0 },
+{ "supplier_event_2", 12, 0, 0, 0, 200000, (RtecScheduler::Criticality_t) 4, (RtecScheduler::Importance_t) 0, 0, 1, 59, 2, 0, (RtecScheduler::Info_Type_t) 0 }
+};
+
+static int infos_size = sizeof(infos)/sizeof(infos[0]);
+
+
+static ACE_Scheduler_Factory::POD_Config_Info configs[] = {
+ { 0, 59, (RtecScheduler::Dispatching_Type_t) 2 },
+ { 1, 58, (RtecScheduler::Dispatching_Type_t) 2 }
+};
+
+static int configs_size = sizeof(configs)/sizeof(configs[0]);
+
+
+// This sets up Scheduler_Factory to use the runtime version.
+int scheduler_factory_setup =
+ ACE_Scheduler_Factory::use_runtime (configs_size, configs, infos_size, infos);
+
+// EOF
diff --git a/TAO/orbsvcs/tests/EC_Config/Service.cpp b/TAO/orbsvcs/tests/EC_Config/Service.cpp
new file mode 100644
index 00000000000..cf9926708a9
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/Service.cpp
@@ -0,0 +1,531 @@
+// $Id$
+
+#include "orbsvcs/Sched/Reconfig_Scheduler.h"
+#include "orbsvcs/Runtime_Scheduler.h"
+#include "orbsvcs/Event/Module_Factory.h"
+#include "orbsvcs/Event_Service_Constants.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+#include "orbsvcs/Event/EC_Kokyu_Factory.h"
+#include "Consumer.h"
+#include "Supplier.h"
+
+#include "Schedule.h"
+
+#include "ace/Get_Opt.h"
+#include "ace/Sched_Params.h"
+#include "ace/Auto_Ptr.h"
+
+ACE_RCSID(EC_Examples, Service, "$Id$")
+
+#define EVENT1TYPE ACE_ES_EVENT_UNDEFINED
+#define EVENT2TYPE ACE_ES_EVENT_UNDEFINED+1
+
+int config_run = 0;
+
+int parse_args (int argc, char *argv[]);
+
+typedef TAO_Reconfig_Scheduler<TAO_MUF_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX> MUF_SCHED_TYPE;
+
+int
+main (int argc, char* argv[])
+{
+ TAO_EC_Kokyu_Factory::init_svcs ();
+
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ // ORB initialization boiler plate...
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (parse_args (argc, argv) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "Usage: Service [-o IOR_file_name]\n"));
+ return 1;
+ }
+
+ CORBA::Object_var object =
+ orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ PortableServer::POA_var poa =
+ PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ PortableServer::POAManager_var poa_manager =
+ poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+#if 0
+ // Obtain a reference to the naming service...
+ CORBA::Object_var naming_obj =
+ orb->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CosNaming::NamingContext_var naming_context =
+ CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+#endif /* 0 */
+
+ // ****************************************************************
+
+ // Create an scheduling service
+ POA_RtecScheduler::Scheduler* sched_impl = 0;
+ if (config_run)
+ {
+ ACE_NEW_RETURN (sched_impl,
+ MUF_SCHED_TYPE,
+ 1);
+ }
+ else
+ {
+ ACE_NEW_RETURN (sched_impl,
+ MUF_SCHED_TYPE (configs_size,
+ configs,
+ infos_size,
+ infos,
+ 0, 0,
+ 0),
+ 1);
+ }
+
+ RtecScheduler::Scheduler_var scheduler =
+ sched_impl->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+#if 0
+ // Bind the scheduler with the naming service so clients
+ // (consumers and suppliers) can resolve it, some (old)
+ // implementations of the EC will try to do the same thing
+ // (yikes!)
+ CosNaming::Name schedule_name (1);
+ schedule_name.length (1);
+ schedule_name[0].id = CORBA::string_dup ("ScheduleService");
+ // Register the servant with the Naming Context....
+ naming_context->rebind (schedule_name, scheduler.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+#endif /* 0 */
+
+ // ****************************************************************
+
+#if 0
+ // Create an event channel implementation...
+ TAO_Default_Module_Factory module_factory;
+ ACE_EventChannel event_channel_impl (scheduler.in (),
+ 1,
+ ACE_DEFAULT_EVENT_CHANNEL_TYPE,
+ &module_factory);
+
+ RtecEventChannelAdmin::EventChannel_var event_channel =
+ event_channel_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+#else
+
+ TAO_EC_Event_Channel_Attributes attributes (poa.in (),
+ poa.in ());
+ attributes.scheduler = scheduler.in (); // no need to dup
+
+ TAO_EC_Event_Channel ec_impl (attributes);
+
+ RtecEventChannelAdmin::EventChannel_var event_channel =
+ ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+#endif /* 0 */
+
+ // ****************************************************************
+
+ // Create consumers, intialize their RT_Info structures, and
+ // connect to the event channel....
+
+ Consumer consumer_high(0),consumer_low(1);
+
+ /*
+ There is 1 HIGH criticality event and one LOW criticality
+ event. The period of the LOW event will vary each run to
+ push events at a certain rate. The idea is to measure
+ the effect of greater LOW throughput on the HIGH throughput.
+ */
+
+ RtecScheduler::handle_t consumer_rt_info_hi = scheduler->create ("Consumer Event Class 0" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ RtecScheduler::handle_t consumer_rt_info_lo = scheduler->create ("Consumer Event Class 1" ACE_ENV_ARG_PARAMETER);
+
+ // Let's say that the execution time for the HIGH event is 1
+ // milliseconds...
+ ACE_Time_Value tv (0, 1000);
+ TimeBase::TimeT time;
+ ORBSVCS_Time::Time_Value_to_TimeT (time, tv);
+ scheduler->set (consumer_rt_info_hi,
+ RtecScheduler::HIGH_CRITICALITY,
+ time, time, time,
+ time,
+ RtecScheduler::VERY_LOW_IMPORTANCE,
+ time,
+ 0,
+ RtecScheduler::OPERATION
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // The execution time and period of the LOW event is set by
+ // command line...
+ tv.set (0, 2000);
+ ORBSVCS_Time::Time_Value_to_TimeT (time, tv);
+ scheduler->set (consumer_rt_info_lo,
+ RtecScheduler::LOW_CRITICALITY,
+ time, time, time,
+ time,
+ RtecScheduler::VERY_LOW_IMPORTANCE,
+ time,
+ 0,
+ RtecScheduler::OPERATION
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_ConsumerQOS_Factory consumer_qos1, consumer_qos2;
+ //consumer_qos.start_disjunction_group ();
+ // The types in the range [0,ACE_ES_EVENT_UNDEFINED) are
+ // reserved for the EC...
+ consumer_qos1.insert_type (EVENT1TYPE,
+ consumer_rt_info_hi);
+ consumer_qos2.insert_type (EVENT2TYPE,
+ consumer_rt_info_lo);
+
+ // The canonical protocol to connect to the EC
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy1 =
+ consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy2 =
+ consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventComm::PushConsumer_var consumer1 =
+ consumer_high._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventComm::PushConsumer_var consumer2 =
+ consumer_low._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG, "connecting consumers\n"));
+ supplier_proxy1->connect_push_consumer (consumer1.in (),
+ consumer_qos1.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ supplier_proxy2->connect_push_consumer (consumer2.in (),
+ consumer_qos2.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG, "consumers connected\n"));
+
+ // ****************************************************************
+
+ Supplier supplier_impl1, supplier_impl2;
+
+ RtecScheduler::handle_t supplier_rt_info1 =
+ scheduler->create ("Supplier Event Class 0" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // The execution times are set to reasonable values, but
+ // actually they are changed on the real execution, i.e. we
+ // lie to the scheduler to obtain right priorities; but we
+ // don't care if the set is schedulable.
+ tv.set (0, 1000);
+ TimeBase::TimeT tmp;
+ ORBSVCS_Time::Time_Value_to_TimeT (tmp, tv);
+ RtecScheduler::Period_t rate = ACE_U64_TO_U32(tmp);
+
+ scheduler->set (supplier_rt_info1,
+ RtecScheduler::HIGH_CRITICALITY,
+ tmp, tmp, tmp,
+ tmp,
+ RtecScheduler::VERY_LOW_IMPORTANCE,
+ tmp,
+ 0,
+ RtecScheduler::OPERATION
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecScheduler::handle_t supplier_rt_info2 =
+ scheduler->create ("Supplier Event Class 1" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // The execution times are set to reasonable values, but
+ // actually they are changed on the real execution, i.e. we
+ // lie to the scheduler to obtain right priorities; but we
+ // don't care if the set is schedulable.
+ tv.set (0, 2000);
+ ORBSVCS_Time::Time_Value_to_TimeT (tmp, tv);
+ rate = ACE_U64_TO_U32(tmp);
+
+ scheduler->set (supplier_rt_info2,
+ RtecScheduler::LOW_CRITICALITY,
+ tmp, tmp, tmp,
+ tmp,
+ RtecScheduler::VERY_LOW_IMPORTANCE,
+ tmp,
+ 0,
+ RtecScheduler::OPERATION
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventComm::EventSourceID supplier_id1 = 1, supplier_id2 = 2;
+ ACE_SupplierQOS_Factory supplier_qos1, supplier_qos2;
+ supplier_qos1.insert (supplier_id1,
+ EVENT1TYPE,
+ supplier_rt_info1,
+ 1); // number of calls, but what does that mean?
+ supplier_qos2.insert (supplier_id2,
+ EVENT2TYPE,
+ supplier_rt_info2,
+ 1); // number of calls, but what does that mean?
+
+ // The canonical protocol to connect to the EC
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::ProxyPushConsumer_var consumer_proxy1 =
+ supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::ProxyPushConsumer_var consumer_proxy2 =
+ supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventComm::PushSupplier_var supplier1 =
+ supplier_impl1._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventComm::PushSupplier_var supplier2 =
+ supplier_impl2._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG, "connecting suppliers\n"));
+ consumer_proxy1->connect_push_supplier (supplier1.in (),
+ supplier_qos1.get_SupplierQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ consumer_proxy2->connect_push_supplier (supplier2.in (),
+ supplier_qos2.get_SupplierQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG, "suppliers connected\n"));
+
+ // ****************************************************************
+
+ // At this point the consumer and supplier are connected to the
+ // EC, they have provided their QoS info to the Scheduling
+ // Service and the EC has informed the Scheduler about the
+ // dependencies between them.
+ // We can now compute the schedule for this configuration...
+
+ // The schedule is returned in this variables....
+
+ if (config_run)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Computing schedule\n"));
+ RtecScheduler::RT_Info_Set_var infos;
+ RtecScheduler::Config_Info_Set_var configs;
+ RtecScheduler::Scheduling_Anomaly_Set_var anomalies;
+
+ // Obtain the range of valid priorities in the current
+ // platform, the scheduler hard-code this values in the
+ // generated file, but in the future we may just use the
+ // "logical" priorities and define the mapping to OS
+ // priorities at run-time.
+ int min_os_priority =
+ ACE_Sched_Params::priority_min (ACE_SCHED_FIFO,
+ ACE_SCOPE_THREAD);
+ int max_os_priority =
+ ACE_Sched_Params::priority_max (ACE_SCHED_FIFO,
+ ACE_SCOPE_THREAD);
+ scheduler->compute_scheduling (min_os_priority,
+ max_os_priority,
+ infos.out (),
+ configs.out (),
+ anomalies.out ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Dump the schedule to a file..
+ ACE_Scheduler_Factory::dump_schedule (infos.in (),
+ configs.in (),
+ anomalies.in (),
+ "schedule.out");
+ }
+
+ // ****************************************************************
+
+ ACE_DEBUG ((LM_DEBUG, "activating EC\n"));
+ ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ ACE_DEBUG ((LM_DEBUG, "EC activated\n"));
+
+ ACE_DEBUG ((LM_DEBUG, "Pushing events\n"));
+
+ // Generate a few events....
+
+ RtecEventComm::EventSet event1 (1);
+ event1.length (1);
+ event1[0].header.type = EVENT1TYPE;
+ event1[0].header.source = supplier_id1;
+ event1[0].header.ttl = 1;
+
+ RtecEventComm::EventSet event2 (1);
+ event2.length (1);
+ event2[0].header.type = EVENT2TYPE;
+ event2[0].header.source = supplier_id2;
+ event2[0].header.ttl = 1;
+
+ for (int i=0; i!=20;++i)
+ {
+ if (i%2 == 0)
+ {
+ consumer_proxy1->push (event1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ else if (i%2 == 1)
+ {
+ consumer_proxy2->push (event2 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_Time_Value rate (0, 10000);
+ ACE_OS::sleep (rate);
+ }
+
+ // ****************************************************************
+
+ // We should do a lot of cleanup (disconnect from the EC,
+ // deactivate all the objects with the POA, etc.) but this is
+ // just a simple demo so we are going to be lazy.
+
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service");
+ return 1;
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+// ****************************************************************
+
+int parse_args (int argc, char *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, "c");
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'c':
+ config_run = 1;
+ break;
+
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-c (config run) "
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates sucessful parsing of the command line
+ return 0;
+}
+
+// ****************************************************************
+
+// Instantiate the templates used by the Reconfig scheduler above
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class auto_ptr<RtecScheduler::Config_Info>;
+template class auto_ptr<RtecScheduler::RT_Info>;
+template class auto_ptr<TAO_Reconfig_Scheduler_Entry>;
+template class ACE_Auto_Basic_Ptr<RtecScheduler::Config_Info>;
+template class ACE_Auto_Basic_Ptr<RtecScheduler::RT_Info>;
+template class ACE_Auto_Basic_Ptr<TAO_Reconfig_Scheduler_Entry>;
+template class ACE_Hash_Map_Manager_Ex<int, RtecScheduler::Config_Info *, ACE_Hash<int>, ACE_Equal_To<int>, TAO_SYNCH_MUTEX>;
+template class ACE_Hash_Map_Manager_Ex<int, RtecScheduler::Dependency_Set *, ACE_Hash<int>, ACE_Equal_To<int>, TAO_SYNCH_MUTEX>;
+template class ACE_Hash_Map_Manager_Ex<int, RtecScheduler::RT_Info *, ACE_Hash<int>, ACE_Equal_To<int>, TAO_SYNCH_MUTEX>;
+template class ACE_Hash_Map_Iterator_Base_Ex<int, RtecScheduler::Config_Info *, ACE_Hash<int>, ACE_Equal_To<int>, TAO_SYNCH_MUTEX>;
+template class ACE_Hash_Map_Iterator_Base_Ex<int, RtecScheduler::Dependency_Set *, ACE_Hash<int>, ACE_Equal_To<int>, TAO_SYNCH_MUTEX>;
+template class ACE_Hash_Map_Iterator_Base_Ex<int, RtecScheduler::RT_Info *, ACE_Hash<int>, ACE_Equal_To<int>, TAO_SYNCH_MUTEX>;
+template class ACE_Hash_Map_Iterator_Ex<int,RtecScheduler::Config_Info*,ACE_Hash<int>,ACE_Equal_To<int>,TAO_SYNCH_MUTEX>;
+template class ACE_Hash_Map_Iterator_Ex<int,RtecScheduler::Dependency_Set*,ACE_Hash<int>,ACE_Equal_To<int>,TAO_SYNCH_MUTEX>;
+template class ACE_Hash_Map_Iterator_Ex<int,RtecScheduler::RT_Info*,ACE_Hash<int>,ACE_Equal_To<int>,TAO_SYNCH_MUTEX>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<int,RtecScheduler::Config_Info*,ACE_Hash<int>,ACE_Equal_To<int>,TAO_SYNCH_MUTEX>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<int,RtecScheduler::Dependency_Set*,ACE_Hash<int>,ACE_Equal_To<int>,TAO_SYNCH_MUTEX>;
+template class ACE_Hash_Map_Reverse_Iterator_Ex<int,RtecScheduler::RT_Info*,ACE_Hash<int>,ACE_Equal_To<int>,TAO_SYNCH_MUTEX>;
+template class ACE_Hash_Map_Entry<int, RtecScheduler::Config_Info *>;
+template class ACE_Hash_Map_Entry<int, RtecScheduler::Dependency_Set *>;
+template class ACE_Hash_Map_Entry<int, RtecScheduler::RT_Info *>;
+template class ACE_RB_Tree<const char *, RtecScheduler::RT_Info *, ACE_Less_Than<const char *>, TAO_SYNCH_MUTEX>;
+template class ACE_RB_Tree_Node<const char *, RtecScheduler::RT_Info *>;
+template class ACE_RB_Tree_Iterator<const char *, RtecScheduler::RT_Info *, ACE_Less_Than<const char *>, TAO_SYNCH_MUTEX>;
+template class ACE_RB_Tree_Iterator_Base<char const *, RtecScheduler::RT_Info *, ACE_Less_Than<char const *>, TAO_SYNCH_MUTEX>;
+template class ACE_RB_Tree_Reverse_Iterator<const char *, RtecScheduler::RT_Info *, ACE_Less_Than<const char *>, TAO_SYNCH_MUTEX>;
+template class TAO_Reconfig_Scheduler<TAO_MUF_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX>;
+template class TAO_RSE_Dependency_Visitor<TAO_MUF_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX>;
+template class TAO_RSE_DFS_Visitor<TAO_MUF_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX>;
+template class TAO_RSE_Priority_Visitor<TAO_MUF_Reconfig_Sched_Strategy>;
+template class TAO_RSE_Propagation_Visitor<TAO_MUF_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX>;
+template class TAO_RSE_SCC_Visitor<TAO_MUF_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX>;
+template class TAO_RSE_Utilization_Visitor<TAO_MUF_Reconfig_Sched_Strategy>;
+
+#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+
+#pragma instantiate auto_ptr<RtecScheduler::Config_Info>
+#pragma instantiate auto_ptr<RtecScheduler::RT_Info>
+#pragma instantiate auto_ptr<TAO_Reconfig_Scheduler_Entry>
+#pragma instantiate ACE_Auto_Basic_Ptr<RtecScheduler::Config_Info>
+#pragma instantiate ACE_Auto_Basic_Ptr<RtecScheduler::RT_Info>
+#pragma instantiate ACE_Auto_Basic_Ptr<TAO_Reconfig_Scheduler_Entry>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<int, RtecScheduler::Config_Info *, ACE_Hash<int>, ACE_Equal_To<int>, TAO_SYNCH_MUTEX>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<int, RtecScheduler::Dependency_Set *, ACE_Hash<int>, ACE_Equal_To<int>, TAO_SYNCH_MUTEX>
+#pragma instantiate ACE_Hash_Map_Manager_Ex<int, RtecScheduler::RT_Info *, ACE_Hash<int>, ACE_Equal_To<int>, TAO_SYNCH_MUTEX>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<int, RtecScheduler::Config_Info *, ACE_Hash<int>, ACE_Equal_To<int>, TAO_SYNCH_MUTEX>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<int, RtecScheduler::Dependency_Set *, ACE_Hash<int>, ACE_Equal_To<int>, TAO_SYNCH_MUTEX>
+#pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<int, RtecScheduler::RT_Info *, ACE_Hash<int>, ACE_Equal_To<int>, TAO_SYNCH_MUTEX>
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<int,RtecScheduler::Config_Info*,ACE_Hash<int>,ACE_Equal_To<int>,TAO_SYNCH_MUTEX>
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<int,RtecScheduler::Dependency_Set*,ACE_Hash<int>,ACE_Equal_To<int>,TAO_SYNCH_MUTEX>
+#pragma instantiate ACE_Hash_Map_Iterator_Ex<int,RtecScheduler::RT_Info*,ACE_Hash<int>,ACE_Equal_To<int>,TAO_SYNCH_MUTEX>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<int,RtecScheduler::Config_Info*,ACE_Hash<int>,ACE_Equal_To<int>,TAO_SYNCH_MUTEX>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<int,RtecScheduler::Dependency_Set*,ACE_Hash<int>,ACE_Equal_To<int>,TAO_SYNCH_MUTEX>
+#pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<int,RtecScheduler::RT_Info*,ACE_Hash<int>,ACE_Equal_To<int>,TAO_SYNCH_MUTEX>
+#pragma instantiate ACE_Hash_Map_Entry<int, RtecScheduler::Config_Info *>
+#pragma instantiate ACE_Hash_Map_Entry<int, RtecScheduler::Dependency_Set *>
+#pragma instantiate ACE_Hash_Map_Entry<int, RtecScheduler::RT_Info *>
+#pragma instantiate ACE_RB_Tree<const char *, RtecScheduler::RT_Info *, ACE_Less_Than<const char *>, TAO_SYNCH_MUTEX>
+#pragma instantiate ACE_RB_Tree_Node<const char *, RtecScheduler::RT_Info *>
+#pragma instantiate ACE_RB_Tree_Iterator<const char *, RtecScheduler::RT_Info *, ACE_Less_Than<const char *>, TAO_SYNCH_MUTEX>
+#pragma instantiate ACE_RB_Tree_Iterator_Base<char const *, RtecScheduler::RT_Info *, ACE_Less_Than<char const *>, TAO_SYNCH_MUTEX>
+#pragma instantiate ACE_RB_Tree_Reverse_Iterator<const char *, RtecScheduler::RT_Info *, ACE_Less_Than<const char *>, TAO_SYNCH_MUTEX>
+#pragma instantiate TAO_Reconfig_Scheduler<TAO_MUF_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX>
+#pragma instantiate TAO_RSE_Dependency_Visitor<TAO_MUF_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX>
+#pragma instantiate TAO_RSE_DFS_Visitor<TAO_MUF_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX>
+#pragma instantiate TAO_RSE_Priority_Visitor<TAO_MUF_Reconfig_Sched_Strategy>
+#pragma instantiate TAO_RSE_Propagation_Visitor<TAO_MUF_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX>
+#pragma instantiate TAO_RSE_SCC_Visitor<TAO_MUF_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX>
+#pragma instantiate TAO_RSE_Utilization_Visitor<TAO_MUF_Reconfig_Sched_Strategy>
+
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/TAO/orbsvcs/tests/EC_Config/Supplier.cpp b/TAO/orbsvcs/tests/EC_Config/Supplier.cpp
new file mode 100644
index 00000000000..badc65b011d
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/Supplier.cpp
@@ -0,0 +1,21 @@
+// $Id$
+
+#include "Supplier.h"
+
+ACE_RCSID(EC_Examples, Supplier, "$Id$")
+
+Supplier::Supplier (void)
+{
+}
+
+void
+Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+}
+
+// ****************************************************************
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+#elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/TAO/orbsvcs/tests/EC_Config/Supplier.h b/TAO/orbsvcs/tests/EC_Config/Supplier.h
new file mode 100644
index 00000000000..b0391f7602b
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/Supplier.h
@@ -0,0 +1,54 @@
+/* -*- C++ -*- */
+// $Id$
+//
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS Real-time Event Channel examples
+//
+// = FILENAME
+// Supplier
+//
+// = AUTHOR
+// Carlos O'Ryan (coryan@cs.wustl.edu)
+//
+// ============================================================================
+
+#ifndef SUPPLIER_H
+#define SUPPLIER_H
+
+#include "orbsvcs/RtecEventCommS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class Supplier : public POA_RtecEventComm::PushSupplier
+{
+ // = TITLE
+ // Simple supplier object
+ //
+ // = DESCRIPTION
+ // This class is a supplier of events.
+ // It simply register for two event typesone event type
+ // The class is just a helper to simplify common tasks in EC
+ // tests, such as subscribing for a range of events, disconnecting
+ // from the EC, informing the driver of shutdown messages, etc.
+ //
+ // There are several ways to connect and disconnect this class,
+ // and it is up to the driver program to use the right one.
+ //
+public:
+ Supplier (void);
+ // Constructor
+
+ // = The RtecEventComm::PushSupplier methods
+
+ virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ // The skeleton methods.
+
+private:
+};
+
+#endif /* SUPPLIER_H */
diff --git a/TAO/orbsvcs/tests/EC_Config/Test.cpp b/TAO/orbsvcs/tests/EC_Config/Test.cpp
new file mode 100644
index 00000000000..cddb1b5eccd
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/Test.cpp
@@ -0,0 +1,109 @@
+// $Id$
+
+#include "ace/Array.h"
+#include "ace/Bound_Ptr.h"
+#include "ace/Synch.h"
+#include "ACEXML/parser/parser/Parser.h"
+#include "ACEXML/common/InputSource.h"
+#include "ACEXML/common/FileCharStream.h"
+#include "ACEXML/common/DefaultHandler.h"
+
+#include "ECConfig.h"
+#include "Config_Factory.h"
+#include "Test_Handler.h"
+
+using namespace TestConfig;
+
+typedef ACE_Strong_Bound_Ptr<Test_Config_Set,ACE_Null_Mutex> TCFG_SET_SPTR;
+
+//NOTE: Read from a formatted file rather than hardcode the configuration. Check ACE_XML.
+
+int
+main (int argc, char** argv)
+{
+ int retval = 0;
+
+ ACEXML_TRY_NEW_ENV
+ {
+ ACEXML_Parser parser;
+
+ // TODO parse args for config filename
+
+ ACEXML_Char *filename = ACE_LIB_TEXT("test.xml");
+ ACEXML_FileCharStream fcs;
+ if ((retval = fcs.open(filename)) != 0) {
+ ACE_DEBUG ((LM_DEBUG, "Could not open file %s\n",filename));
+ return retval;
+ }
+
+ ACEXML_InputSource is (&fcs);
+
+ Test_Handler handler (filename);
+ ACEXML_DefaultHandler dflt;
+
+ parser.setContentHandler (&handler);
+ parser.setDTDHandler (&dflt);
+ parser.setErrorHandler (&handler);
+ parser.setEntityResolver (&dflt);
+
+ parser.parse(&is);
+ ACEXML_TRY_CHECK;
+
+ // TODO configure according to parsed XML
+ }
+ ACEXML_CATCH (ACEXML_SAXException, ex)
+ {
+ ACE_UNUSED_ARG (ex);
+ ACE_DEBUG ((LM_ERROR, ACE_TEXT ("Exception occurred. Exiting...\n")));
+ return 1;
+ }
+ ACEXML_ENDTRY;
+
+#if 0
+ ConfigFactory::Default_Config_Factory fact;
+ fact.init(argc,argv);
+
+ Test_Config *backend = fact.create_testconfig();
+ if (0 == backend) {
+ ACE_DEBUG((LM_DEBUG, "Error: could not create back end!\n"));
+ return 1;
+ }
+
+ TCFG_SET_SPTR cfg_ptr(new Test_Config_Set(2));
+
+ (*cfg_ptr)[0] = new test_config_t();
+ (*cfg_ptr)[0]->type = 0;
+ (*cfg_ptr)[0]->period = 1000;
+ (*cfg_ptr)[0]->criticality = HIGH_CRITICALITY;
+ (*cfg_ptr)[0]->importance = VERY_LOW_IMPORTANCE;
+ (*cfg_ptr)[0]->num_entities = 10;
+
+ (*cfg_ptr)[1] = new test_config_t();
+ (*cfg_ptr)[1]->type = 1;
+ (*cfg_ptr)[1]->period = 2000;
+ (*cfg_ptr)[1]->criticality = LOW_CRITICALITY;
+ (*cfg_ptr)[1]->importance = VERY_LOW_IMPORTANCE;
+ (*cfg_ptr)[1]->num_entities = 10;
+
+ // PROBLEM: occasional segfault on run and configure
+ int retval = 0;
+ if ((retval = backend->configure(TCFG_SET_WPTR(cfg_ptr))) != 0) {
+ ACE_DEBUG((LM_DEBUG, "Error configuring back end! (%d)\n",retval));
+ return retval;
+ }
+
+ if ((retval = backend->run()) != 0) {
+ ACE_DEBUG((LM_DEBUG, "Error running back end! (%d)\n",retval));
+ return retval;
+ }
+
+ for(size_t i=0; i<cfg_ptr->size(); ++i) {
+ delete (*cfg_ptr)[i];
+ }
+
+ fact.destroy_testconfig(backend);
+ fact.fini();
+#endif /* 0 */
+
+ return retval;
+}
diff --git a/TAO/orbsvcs/tests/EC_Config/TestConfig.h b/TAO/orbsvcs/tests/EC_Config/TestConfig.h
new file mode 100644
index 00000000000..8294348537f
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/TestConfig.h
@@ -0,0 +1,125 @@
+/* -*- C++ -*- */
+// $Id$
+//
+// ============================================================================
+//
+// = FILENAME
+// TestConfig
+//
+// = AUTHOR
+// Bryan Thrall (thrall@cse.wustl.edu)
+//
+// ============================================================================
+
+#ifndef TESTCONFIG_H
+#define TESTCONFIG_H
+
+#include "ace/Array.h"
+#include "ace/Bound_Ptr.h"
+#include "ace/Synch.h" //for ACE_Null_Mutex
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+namespace TestConfig {
+
+struct test_config_t;
+typedef ACE_Array<test_config_t*> Test_Config_Set;
+typedef ACE_Weak_Bound_Ptr<Test_Config_Set,ACE_Null_Mutex> TCFG_SET_WPTR;
+
+// Entity_Type_t is used to distinguish different types of entities
+// (such as Event Channel events and Distributable Threads). Not exactly
+// an enumeration of those types, but it should take on reasonably
+// distinct values for each.
+typedef unsigned long Entity_Type_t;
+
+typedef long Period_t;
+
+enum Criticality_t {
+// Defines the criticality of the entity.
+ VERY_LOW_CRITICALITY,
+ LOW_CRITICALITY,
+ MEDIUM_CRITICALITY,
+ HIGH_CRITICALITY,
+ VERY_HIGH_CRITICALITY
+};
+
+enum Importance_t {
+// Defines the importance of the entity,
+// which can be used as a "tie-breaker" when
+// other scheduling parameters are equal.
+ VERY_LOW_IMPORTANCE,
+ LOW_IMPORTANCE,
+ MEDIUM_IMPORTANCE,
+ HIGH_IMPORTANCE,
+ VERY_HIGH_IMPORTANCE
+};
+
+
+struct test_config_t
+// = TITLE
+// Test configuration information for the back-end.
+//
+// = DESCRIPTION
+// The QoS and number of tasks for each
+// test "entity" described by the following
+// information.
+{
+ // The entity type should uniquely identify the
+ // set of entities configured by this struct.
+ Entity_Type_t type;
+
+ // This expresses the rate at which entities are
+ // pushed.
+ Period_t period;
+
+ // Entity Criticality (user assigned significance).
+ Criticality_t criticality;
+
+ // Entity importance, used to "break ties".
+ Importance_t importance;
+
+ // Number of entities to push through the back-end. This is
+ // effectively a termination condition for the test, since it will
+ // terminate once all num_entities entities have been pushed for
+ // each test_config_t used to configure the back-end.
+ long num_entities;
+};
+
+class Test_Config {
+ // = TITLE
+ // Interface for configuring the test back-end.
+ //
+ // = DESCRIPTION
+ // This class provides an interface for configuring the back-end of the test.
+ // For example, the Event Channel might be the back-end, so an adapter
+ // implementing this interface would be used to configure the EC in that case.
+ //
+public:
+ Test_Config (void) {};
+
+ virtual ~Test_Config (void) {};
+
+ virtual int configure (TCFG_SET_WPTR configs) = 0;
+ // Configures the back-end. Each test_config_t in the set specifies
+ // the configuration of a separate type of entity. Returns 0 when
+ // the configuration is successful, non-zero otherwise. An
+ // ACE_Weak_Bound_Ptr is used because the TestConfig might want to
+ // keep a pointer to the Test_Config_Set but should not take
+ // possession of the set (that is, control when the set is deleted).
+
+ virtual int run (void) = 0;
+ // Runs the configured back-end. Returns 0 if the run encountered
+ // no errors, non-zero otherwise. Entities are pushed periodically
+ // according to their respective test_config_t's until num_entities
+ // are pushed of each test_config_t.
+
+ //NOTE: It might be useful to distinguish between a run which
+ //returns after the last entity was pushed and one which returns
+ //after the last entity was received at its destination.
+};
+
+} /* namespace TestConfig */
+
+#endif /* TESTCONFIG_H */
diff --git a/TAO/orbsvcs/tests/EC_Config/Test_Handler.cpp b/TAO/orbsvcs/tests/EC_Config/Test_Handler.cpp
new file mode 100644
index 00000000000..d19d542bf46
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/Test_Handler.cpp
@@ -0,0 +1,204 @@
+// -*- C++ -*- $Id$
+
+#include "Test_Handler.h"
+#include "ace/ACE.h"
+#include "ace/Log_Msg.h"
+
+// TODO Create test_config_t's based on XML using entities described in testconfig.dtd
+
+Test_Handler::Test_Handler (ACEXML_Char* fileName)
+ : configs_(0),
+ fileName_(ACE::strnew (fileName))
+{
+
+}
+
+Test_Handler::~Test_Handler (void)
+{
+ delete[] this->fileName_;
+
+ for(size_t i=0; i<configs_.size(); ++i) {
+ delete configs_[i];
+ }
+}
+
+const TestConfig::Test_Config_Set &
+Test_Handler::get_configs (void) const
+{
+ return this->configs_;
+}
+
+
+void
+Test_Handler::characters (const ACEXML_Char *cdata,
+ int start,
+ int end ACEXML_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+{
+
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("* Event characters () ** start: %d end: %d ***************\n%s\n- End event characters () ---------------\n"),
+ start, end, cdata));
+}
+
+void
+Test_Handler::endDocument (ACEXML_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+{
+
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("* Event endDocument () ***************\n")));
+}
+
+void
+Test_Handler::endElement (const ACEXML_Char *uri,
+ const ACEXML_Char *name,
+ const ACEXML_Char *qName
+ ACEXML_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+{
+
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("* Event endElement (%s, %s, %s) ***************\n"),
+ uri, name, qName));
+}
+
+void
+Test_Handler::endPrefixMapping (const ACEXML_Char *prefix
+ ACEXML_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+{
+
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("* Event endPrefixMapping (%s) ***************\n"),
+ prefix));
+}
+
+void
+Test_Handler::ignorableWhitespace (const ACEXML_Char *,
+ int,
+ int
+ ACEXML_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+{
+
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("* Event ignorableWhitespace () ***************\n")));
+}
+
+void
+Test_Handler::processingInstruction (const ACEXML_Char *target,
+ const ACEXML_Char *data
+ ACEXML_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+{
+
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("* Event processingInstruction (%s, %s) ***************\n"),
+ target, data));
+}
+
+void
+Test_Handler::setDocumentLocator (ACEXML_Locator * locator)
+{
+
+ this->locator_ = locator;
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("* Event setDocumentLocator () ***************\n")));
+}
+
+void
+Test_Handler::skippedEntity (const ACEXML_Char *name
+ ACEXML_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+{
+
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("* Event skippedEntity (%s) ***************\n"),
+ name));
+}
+
+void
+Test_Handler::startDocument (ACEXML_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+{
+
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("* Event startDocument () ***************\n")));
+}
+
+void
+Test_Handler::startElement (const ACEXML_Char *uri,
+ const ACEXML_Char *name,
+ const ACEXML_Char *qName,
+ ACEXML_Attributes *alist
+ ACEXML_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+{
+
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("* Event startElement (%s, %s, %s) ***************\n"),
+ uri, name, qName));
+
+ if (alist != 0)
+ for (size_t i = 0; i < alist->getLength (); ++i)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT (" %s = \"%s\"\n"),
+ alist->getQName (i), alist->getValue (i)));
+ }
+}
+
+void
+Test_Handler::startPrefixMapping (const ACEXML_Char * prefix,
+ const ACEXML_Char * uri ACEXML_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+{
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("* Event startPrefixMapping () ***************\n")));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("Prefix = %s, URI = %s\n"), prefix, uri));
+}
+
+// Methods inherited from ACEXML_ErrorHandler.
+
+/*
+ * Receive notification of a recoverable error.
+ */
+void
+Test_Handler::error (ACEXML_SAXParseException & ex ACEXML_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+{
+
+ ACE_DEBUG ((LM_DEBUG, "%s:%d:%d ", this->fileName_,
+ this->locator_->getLineNumber(),
+ this->locator_->getColumnNumber()));
+ ex.print();
+}
+
+void
+Test_Handler::fatalError (ACEXML_SAXParseException& ex ACEXML_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+{
+
+ ACE_DEBUG ((LM_DEBUG, "%s:%d:%d ", this->fileName_,
+ this->locator_->getLineNumber(),
+ this->locator_->getColumnNumber()));
+ ex.print();
+}
+
+void
+Test_Handler::warning (ACEXML_SAXParseException & ACEXML_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+{
+ // No-op.
+}
diff --git a/TAO/orbsvcs/tests/EC_Config/Test_Handler.h b/TAO/orbsvcs/tests/EC_Config/Test_Handler.h
new file mode 100644
index 00000000000..5c2b332a255
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/Test_Handler.h
@@ -0,0 +1,168 @@
+// $Id$
+
+//=============================================================================
+/**
+ * @file Test_Handler.h
+ *
+ * $Id$
+ *
+ * @author Bryan Thrall <thrall@cse.wustl.edu>
+ */
+//=============================================================================
+
+
+#ifndef TEST_HANDLER_H
+#define TEST_HANDLER_H
+
+#include "ACEXML/common/ContentHandler.h"
+#include "ACEXML/common/ErrorHandler.h"
+
+#include "TestConfig.h"
+
+/**
+ * @class Test_Handler
+ *
+ * @brief Test_Handler is a SAX event handler which parses testconfig.dtd XML
+ *
+ * This SAX event handler parses XML according to testconfig.dtd, producing a
+ * set of test_config_t's.
+ */
+class Test_Handler : public ACEXML_ContentHandler, public ACEXML_ErrorHandler
+{
+public:
+ /*
+ * Default constructor.
+ */
+ Test_Handler (ACEXML_Char* fileName);
+
+ /*
+ * Default destructor.
+ */
+ virtual ~Test_Handler (void);
+
+ /**
+ * Returns a reference to the Handler's internal set of
+ * test_config_t's. The Handler retains ownership of the
+ * (dynamically allocated) test_config_t's in the set.
+ */
+ const TestConfig::Test_Config_Set &get_configs (void) const;
+
+ // Methods inherited from ACEXML_ContentHandler.
+
+ /*
+ * Receive notification of character data.
+ */
+ virtual void characters (const ACEXML_Char *ch,
+ int start,
+ int length ACEXML_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+ ;
+
+ /*
+ * Receive notification of the end of a document.
+ */
+ virtual void endDocument (ACEXML_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+ ;
+
+ /*
+ * Receive notification of the end of an element.
+ */
+ virtual void endElement (const ACEXML_Char *namespaceURI,
+ const ACEXML_Char *localName,
+ const ACEXML_Char *qName ACEXML_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+ ;
+
+ /*
+ * End the scope of a prefix-URI mapping.
+ */
+ virtual void endPrefixMapping (const ACEXML_Char *prefix ACEXML_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+ ;
+
+ /*
+ * Receive notification of ignorable whitespace in element content.
+ */
+ virtual void ignorableWhitespace (const ACEXML_Char *ch,
+ int start,
+ int length ACEXML_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+ ;
+
+ /*
+ * Receive notification of a processing instruction.
+ */
+ virtual void processingInstruction (const ACEXML_Char *target,
+ const ACEXML_Char *data ACEXML_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+ ;
+
+ /*
+ * Receive an object for locating the origin of SAX document events.
+ */
+ virtual void setDocumentLocator (ACEXML_Locator *locator) ;
+
+ /*
+ * Receive notification of a skipped entity.
+ */
+ virtual void skippedEntity (const ACEXML_Char *name ACEXML_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+ ;
+
+ /*
+ * Receive notification of the beginning of a document.
+ */
+ virtual void startDocument (ACEXML_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+ ;
+
+ /*
+ * Receive notification of the beginning of an element.
+ */
+ virtual void startElement (const ACEXML_Char *namespaceURI,
+ const ACEXML_Char *localName,
+ const ACEXML_Char *qName,
+ ACEXML_Attributes *atts ACEXML_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+ ;
+
+ /*
+ * Begin the scope of a prefix-URI Namespace mapping.
+ */
+ virtual void startPrefixMapping (const ACEXML_Char *prefix,
+ const ACEXML_Char *uri ACEXML_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+ ;
+
+ // Methods inherited from ACEXML_ErrorHandler.
+
+ /*
+ * Receive notification of a recoverable error.
+ */
+ virtual void error (ACEXML_SAXParseException &exception ACEXML_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+ ;
+
+ /*
+ * Receive notification of a non-recoverable error.
+ */
+ virtual void fatalError (ACEXML_SAXParseException &exception ACEXML_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+ ;
+
+ /*
+ * Receive notification of a warning.
+ */
+ virtual void warning (ACEXML_SAXParseException &exception ACEXML_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+ ;
+private:
+ TestConfig::Test_Config_Set configs_;
+
+ ACEXML_Char* fileName_;
+ ACEXML_Locator* locator_;
+
+};
+
+#endif /* TEST_HANDLER_H */
diff --git a/TAO/orbsvcs/tests/EC_Config/svc.conf b/TAO/orbsvcs/tests/EC_Config/svc.conf
new file mode 100644
index 00000000000..bfbfac829b5
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/svc.conf
@@ -0,0 +1,2 @@
+# $Id$
+static EC_Factory "-ECProxyPushConsumerCollection mt:immediate:list -ECProxyPushSupplierCollection mt:immediate:list -ECdispatching kokyu -ECscheduling kokyu -ECfiltering kokyu -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"
diff --git a/TAO/orbsvcs/tests/EC_Config/svc.conf.xml b/TAO/orbsvcs/tests/EC_Config/svc.conf.xml
new file mode 100644
index 00000000000..2bc3e1255ca
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/svc.conf.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0'?>
+<!-- Converted from ./orbsvcs/examples/RtEC/Schedule/svc.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- $Id$ -->
+ <static id="EC_Factory" params="-ECProxyPushConsumerCollection mt:immediate:list -ECProxyPushSupplierCollection mt:immediate:list -ECdispatching kokyu -ECscheduling kokyu -ECfiltering kokyu -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"/>
+</ACE_Svc_Conf>
diff --git a/TAO/orbsvcs/tests/EC_Config/test.xml b/TAO/orbsvcs/tests/EC_Config/test.xml
new file mode 100644
index 00000000000..5a37434eb0f
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/test.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!DOCTYPE testconfig SYSTEM "testconfig.dtd">
+<testconfig>
+ <test_config_t>
+ <type>0</type>
+ <period>1000</period>
+ <criticality value="HIGH" />
+ <importance value="VERY_LOW" />
+ <num_entities>10</num_entities>
+ </test_config_t>
+ <test_config_t>
+ <type>1</type>
+ <period>2000</period>
+ <criticality value="LOW"/>
+ <importance value="VERY_LOW"/>
+ <num_entities>10</num_entities>
+ </test_config_t>
+</testconfig> \ No newline at end of file
diff --git a/TAO/orbsvcs/tests/EC_Config/testconfig.dtd b/TAO/orbsvcs/tests/EC_Config/testconfig.dtd
new file mode 100644
index 00000000000..6330b60e817
--- /dev/null
+++ b/TAO/orbsvcs/tests/EC_Config/testconfig.dtd
@@ -0,0 +1,9 @@
+ <!ELEMENT testconfig (test_config_t*) >
+ <!ELEMENT test_config_t (type,period,criticality,importance,num_entities) >
+ <!ELEMENT type (#PCDATA) >
+ <!ELEMENT period (#PCDATA) >
+ <!ELEMENT criticality EMPTY >
+ <!ELEMENT importance EMPTY >
+ <!ELEMENT num_entities (#PCDATA) >
+ <!ATTLIST criticality value (VERY_LOW|LOW|MEDIUM|HIGH|VERY_HIGH) #REQUIRED >
+ <!ATTLIST importance value (VERY_LOW|LOW|MEDIUM|HIGH|VERY_HIGH) #REQUIRED >