summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/tests/Event
diff options
context:
space:
mode:
authorWilliam R. Otte <wotte@dre.vanderbilt.edu>2006-07-24 15:50:21 +0000
committerWilliam R. Otte <wotte@dre.vanderbilt.edu>2006-07-24 15:50:21 +0000
commit3aff90f4a822fcf5d902bbfbcc9fa931d6191a8c (patch)
tree197c810e5f5bce17b1233a7cb8d7b50c0bcd25e2 /TAO/orbsvcs/tests/Event
parent6b846cf03c0bcbd8c276cb0af61a181e5f98eaae (diff)
downloadATCD-3aff90f4a822fcf5d902bbfbcc9fa931d6191a8c.tar.gz
Repo restructuring
Diffstat (limited to 'TAO/orbsvcs/tests/Event')
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Atomic_Reconnect.cpp317
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Atomic_Reconnect.h58
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/BCast.cpp157
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/BCast.h85
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Bitmask.cpp254
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Complex.cpp238
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Control.cpp205
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Control.h50
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Disconnect.cpp223
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Event_Basic.mpc93
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Gateway.cpp359
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/MT_Disconnect.cpp254
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/MT_Disconnect.h45
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Makefile.am680
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Negation.cpp214
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Observer.cpp415
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Observer.h120
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/README43
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Random.cpp578
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Random.h183
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Reconnect.cpp242
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Reconnect.h75
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Schedule.cpp215
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Schedule.h85
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Shutdown.cpp89
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Shutdown.h59
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Timeout.cpp205
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/Wildcard.cpp319
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/control.conf2
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/control.conf.xml6
-rwxr-xr-xTAO/orbsvcs/tests/Event/Basic/exhaustive_test.pl60
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/mt.svc.conf2
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/mt.svc.conf.xml6
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/observer.conf2
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/observer.conf.xml6
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/rteventtestexe.mpb13
-rwxr-xr-xTAO/orbsvcs/tests/Event/Basic/run_test.pl101
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/sched.conf3
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/sched.conf.xml8
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/svc.complex.conf2
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/svc.complex.conf.xml6
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/svc.conf2
-rw-r--r--TAO/orbsvcs/tests/Event/Basic/svc.conf.xml6
-rw-r--r--TAO/orbsvcs/tests/Event/Makefile.am16
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Common/ECMcastTests_export.h40
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Common/ECMcastTests_lib.mpc7
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Common/EC_Wrapper.cpp163
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Common/EC_Wrapper.h97
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Common/Gateway_EC.cpp162
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Common/Gateway_EC.h50
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Common/Makefile.am51
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Complex/Complex.mpc53
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Complex/Constants.h9
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Complex/Makefile.am141
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Complex/README55
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Complex/consumer-ec.conf3
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Complex/consumer.cpp229
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Complex/gateway-ec.cpp13
-rwxr-xr-xTAO/orbsvcs/tests/Event/Mcast/Complex/run_test.pl215
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Complex/supplier-ec.conf3
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Complex/supplier.cpp120
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Makefile.am16
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventConsumerMain.cpp109
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventConsumer_i.cpp54
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventConsumer_i.h29
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventSupplierMain.cpp245
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventSupplier_i.cpp26
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventSupplier_i.h24
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/README138
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/RTEC_MCast_Federated.mpc25
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/SimpleAddressServer.cpp18
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/SimpleAddressServer.h25
-rwxr-xr-xTAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/run_test.pl142
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/supplier.conf2
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Simple/Constants.h6
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Simple/Makefile.am141
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Simple/README62
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Simple/Simple.mpc53
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Simple/consumer-ec.conf4
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Simple/consumer.cpp195
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Simple/gateway-ec.cpp15
-rwxr-xr-xTAO/orbsvcs/tests/Event/Mcast/Simple/run_test.pl235
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Simple/supplier-ec.conf32
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Simple/supplier.cpp107
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Simple/udp-consumer-ec.conf4
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Simple/udp-supplier-ec.conf32
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Two_Way/Constants.h7
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Two_Way/Makefile.am102
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Two_Way/README57
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Two_Way/Two_Way.mpc36
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Two_Way/application.cpp666
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Two_Way/gateway-ec.cpp14
-rw-r--r--TAO/orbsvcs/tests/Event/Mcast/Two_Way/gateway.conf3
-rwxr-xr-xTAO/orbsvcs/tests/Event/Mcast/Two_Way/run_test.pl205
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/Connect.cpp400
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/Connect.h133
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/Event_Performance.mpc38
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/Inversion.cpp176
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/Inversion.h60
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/Latency.cpp421
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/Latency.h100
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/Latency_Server.cpp180
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/Makefile.am229
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/README50
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/Throughput.cpp61
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/Throughput.h56
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/ec.list.conf2
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/ec.list.conf.xml6
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/ec.mt.conf2
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/ec.mt.conf.xml6
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/ec.rb_tree.conf2
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/ec.rb_tree.conf.xml6
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/ec.st.conf2
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/ec.st.conf.xml6
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/eventperftestexe.mpb13
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/latency.conf4
-rw-r--r--TAO/orbsvcs/tests/Event/Performance/latency.conf.xml8
-rwxr-xr-xTAO/orbsvcs/tests/Event/Performance/run_test.pl65
-rw-r--r--TAO/orbsvcs/tests/Event/lib/Consumer.cpp167
-rw-r--r--TAO/orbsvcs/tests/Event/lib/Consumer.h121
-rw-r--r--TAO/orbsvcs/tests/Event/lib/Counting_Consumer.cpp116
-rw-r--r--TAO/orbsvcs/tests/Event/lib/Counting_Consumer.h72
-rw-r--r--TAO/orbsvcs/tests/Event/lib/Counting_Supplier.cpp225
-rw-r--r--TAO/orbsvcs/tests/Event/lib/Counting_Supplier.h129
-rw-r--r--TAO/orbsvcs/tests/Event/lib/Driver.cpp1027
-rw-r--r--TAO/orbsvcs/tests/Event/lib/Driver.h329
-rw-r--r--TAO/orbsvcs/tests/Event/lib/Driver.i7
-rw-r--r--TAO/orbsvcs/tests/Event/lib/Event_lib.mpc10
-rw-r--r--TAO/orbsvcs/tests/Event/lib/Makefile.am58
-rw-r--r--TAO/orbsvcs/tests/Event/lib/README5
-rw-r--r--TAO/orbsvcs/tests/Event/lib/Supplier.cpp298
-rw-r--r--TAO/orbsvcs/tests/Event/lib/Supplier.h193
-rw-r--r--TAO/orbsvcs/tests/Event/lib/ectest_export.h40
133 files changed, 15164 insertions, 0 deletions
diff --git a/TAO/orbsvcs/tests/Event/Basic/Atomic_Reconnect.cpp b/TAO/orbsvcs/tests/Event/Basic/Atomic_Reconnect.cpp
new file mode 100644
index 00000000000..6e4b0d31665
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Atomic_Reconnect.cpp
@@ -0,0 +1,317 @@
+// $Id$
+
+#include "Atomic_Reconnect.h"
+#include "Counting_Supplier.h"
+
+#include "ace/OS_NS_unistd.h"
+
+#include "orbsvcs/Time_Utilities.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+
+ACE_RCSID (EC_Tests,
+ Atomic_Reconnect,
+ "$Id$")
+
+const int event_type = 20;
+const int event_source = 10;
+
+int
+main (int argc, char* argv[])
+{
+ TAO_EC_Default_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;
+
+ 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;
+
+ // ****************************************************************
+
+ TAO_EC_Event_Channel_Attributes attributes (poa.in (),
+ poa.in ());
+ attributes.consumer_reconnect = 1;
+ attributes.supplier_reconnect = 1;
+
+ TAO_EC_Event_Channel ec_impl (attributes);
+ ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::EventChannel_var event_channel =
+ ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+
+ // ****************************************************************
+
+ // Obtain the consumer admin..
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain the supplier admin..
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Supplier supplier0;
+ EC_Counting_Supplier supplier1;
+
+ supplier0.connect (supplier_admin.in (),
+ event_source,
+ event_type,
+ event_source,
+ event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ supplier1.connect (supplier_admin.in (),
+ event_source,
+ event_type + 1,
+ event_source,
+ event_type + 1
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ Consumer consumer01 ("Consumer/01", event_type);
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+ ACE_ConsumerQOS_Factory consumer_qos0;
+ consumer_qos0.start_disjunction_group ();
+ consumer_qos0.insert (event_source, event_type, 0);
+
+ ACE_ConsumerQOS_Factory consumer_qos1;
+ consumer_qos1.start_disjunction_group ();
+ consumer_qos1.insert (event_source, event_type + 1, 0);
+
+ ACE_ConsumerQOS_Factory consumer_qos01;
+ consumer_qos01.start_disjunction_group ();
+ consumer_qos01.insert (event_source, event_type, 0);
+ consumer_qos01.insert (event_source, event_type + 1, 0);
+
+ consumer01.connect (consumer_admin.in (),
+ consumer_qos01.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ Consumer consumer0 ("Consumer/0", event_type);
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+ consumer0.connect (consumer_admin.in (),
+ consumer_qos0.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ Consumer consumer1 ("Consumer/1", event_type);
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+ consumer1.connect (consumer_admin.in (),
+ consumer_qos1.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Supplier_Task task0 (&supplier0);
+ EC_Counting_Supplier_Task task1 (&supplier1);
+
+ task0.activate ();
+ task1.activate ();
+
+ // ****************************************************************
+
+ const int iterations = 1000;
+
+ for (int i = 0; i != iterations; ++i)
+ {
+ ACE_Time_Value tv (0, 10000);
+ consumer0.connect (consumer_admin.in (),
+ consumer_qos0.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ consumer1.connect (consumer_admin.in (),
+ consumer_qos1.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ if (i % 2 == 0)
+ {
+ consumer01.connect (consumer_admin.in (),
+ consumer_qos0.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ else
+ {
+ consumer01.connect (consumer_admin.in (),
+ consumer_qos01.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ ACE_OS::sleep (tv);
+ }
+
+ task0.stop ();
+ task1.stop ();
+
+ ACE_Thread_Manager::instance ()->wait ();
+
+
+ // ****************************************************************
+
+ // Cleanup..
+
+ consumer01.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ consumer1.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ consumer0.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ supplier1.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier0.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ ACE_DEBUG ((LM_DEBUG,
+ "Task 0 pushed %d events\n", task0.push_count ()));
+ ACE_DEBUG ((LM_DEBUG,
+ "Task 1 pushed %d events\n", task1.push_count ()));
+ ACE_DEBUG ((LM_DEBUG,
+ "Supplier 0 pushed %d events\n", supplier0.event_count));
+ ACE_DEBUG ((LM_DEBUG,
+ "Supplier 1 pushed %d events\n", supplier1.event_count));
+ consumer0.dump_results (task0.push_count (), 5);
+ consumer1.dump_results (task1.push_count (), 5);
+ consumer01.dump_results (task0.push_count (),
+ task1.push_count (),
+ 1);
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service");
+ return 1;
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+// ****************************************************************
+
+Consumer::Consumer (const char* name,
+ int base_type)
+ : EC_Counting_Consumer (name),
+ event_base_count (0),
+ event_base_type_ (base_type)
+{
+}
+
+void
+Consumer::dump_results (int expected_count,
+ int tolerance)
+{
+ this->EC_Counting_Consumer::dump_results (expected_count, tolerance);
+}
+
+void
+Consumer::dump_results (int base_count,
+ int extra_count,
+ int tolerance)
+{
+ int diff = this->event_base_count - base_count;
+ if (diff > tolerance || diff < -tolerance)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ERROR - %s unexpected number of base events <%d>\n",
+ this->name_,
+ this->event_base_count));
+ }
+ else
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "%s - number of base events <%d> within margins\n",
+ this->name_,
+ this->event_base_count));
+ }
+
+ if (this->event_count < CORBA::ULong(base_count)
+ || this->event_count >= CORBA::ULong(base_count + extra_count))
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ERROR - %s unexpected number of events <%d,%d,%d>\n",
+ this->name_,
+ base_count,
+ this->event_count,
+ base_count + extra_count));
+ }
+ else
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "%s number of events "
+ "<%d,%d,%d> within margins\n",
+ this->name_,
+ base_count,
+ this->event_count,
+ base_count + extra_count));
+ }
+}
+
+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,
+ "%s (%P|%t) no events\n", this->name_));
+ return;
+ }
+
+ ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock_);
+ this->event_count++;
+
+ // ACE_DEBUG ((LM_DEBUG,
+ // "Consumer %s has received %d events\n",
+ // this->name_, this->event_count));
+
+ if (events[0].header.type == this->event_base_type_)
+ this->event_base_count++;
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/Atomic_Reconnect.h b/TAO/orbsvcs/tests/Event/Basic/Atomic_Reconnect.h
new file mode 100644
index 00000000000..1cb23396ef5
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Atomic_Reconnect.h
@@ -0,0 +1,58 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file Atomic_Reconnect.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan (coryan@cs.wustl.edu)
+ */
+//=============================================================================
+
+
+#ifndef EC_ATOMIC_RECONNECT_H
+#define EC_ATOMIC_RECONNECT_H
+
+#include "Counting_Consumer.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class Consumer
+ *
+ * @brief Simple consumer object
+ *
+ */
+class Consumer : public EC_Counting_Consumer
+{
+public:
+ /// Constructor
+ Consumer (const char* name,
+ int event_base_type);
+
+ void dump_results (int expected_count,
+ int tolerance);
+ void dump_results (int base_count,
+ int extra_count,
+ int tolerance);
+
+ // = The RtecEventComm::PushConsumer methods
+
+ virtual void push (const RtecEventComm::EventSet& events
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// Number of events of type <event_base_type_> received.
+ CORBA::ULong event_base_count;
+
+private:
+ /// Base event type
+ int event_base_type_;
+
+ /// Synchronize access to the counter
+ TAO_SYNCH_MUTEX lock_;
+};
+
+#endif /* EC_ATOMIC_RECONNECT_H */
diff --git a/TAO/orbsvcs/tests/Event/Basic/BCast.cpp b/TAO/orbsvcs/tests/Event/Basic/BCast.cpp
new file mode 100644
index 00000000000..93e068b6d84
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/BCast.cpp
@@ -0,0 +1,157 @@
+// $Id$
+
+#include "BCast.h"
+#include "Consumer.h"
+#include "Supplier.h"
+#include "orbsvcs/Event/ECG_Mcast_Gateway.h"
+#include "tao/ORB_Core.h"
+#include "ace/Arg_Shifter.h"
+#include "ace/INET_Addr.h"
+
+ACE_RCSID (EC_Tests_Basic,
+ BCast,
+ "$Id$")
+
+int
+main (int argc, char *argv [])
+{
+ EC_BCast driver;
+ return driver.run (argc, argv);
+}
+
+// ****************************************************************
+
+EC_BCast::EC_BCast (void)
+ : bcast_address_ ("255.255.255.255"),
+ bcast_port_ (12345)
+{
+}
+
+int
+EC_BCast::parse_args (int& argc, char* argv[])
+{
+ if (this->EC_Driver::parse_args (argc, argv) != 0)
+ return -1;
+
+ ACE_Arg_Shifter arg_shifter (argc, argv);
+
+ while (arg_shifter.is_anything_left ())
+ {
+ const char *arg = arg_shifter.get_current ();
+
+ if (ACE_OS::strcmp (arg, "-port") == 0)
+ {
+ arg_shifter.consume_arg ();
+ this->bcast_port_ = ACE_OS::atoi (arg_shifter.get_current ());
+ }
+
+ else if (ACE_OS::strcmp (arg, "-address") == 0)
+ {
+ arg_shifter.consume_arg ();
+ this->bcast_address_ = arg_shifter.get_current ();
+ }
+
+ arg_shifter.ignore_arg ();
+ }
+
+ return 0;
+}
+
+void
+EC_BCast::print_args (void) const
+{
+ this->EC_Driver::print_args ();
+}
+
+void
+EC_BCast::print_usage (void)
+{
+ this->EC_Driver::print_usage ();
+}
+
+void
+EC_BCast::modify_attributes (TAO_EC_Event_Channel_Attributes&)
+{
+}
+
+void
+EC_BCast::execute_test (ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Subscription determining which EC events will get sent out on the
+ // UDP socket.
+ RtecEventChannelAdmin::ConsumerQOS sub;
+ int shutdown_event_type;
+ this->build_consumer_qos (0, sub, shutdown_event_type ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Obtain UDP address in the string format for Gateway initialization.
+ char address_server_arg [256];
+ ACE_INET_Addr udp_addr;
+ if (udp_addr.set (this->bcast_port_, this->bcast_address_) == -1
+ || udp_addr.addr_to_string (address_server_arg, 256) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "%N (%l): Problems with specified UDP address\n"));
+ return;
+ }
+
+ // Set up UDP federation.
+ TAO_ECG_Mcast_Gateway::Attributes lAttributes;
+ lAttributes.address_server_type = TAO_ECG_Mcast_Gateway::ECG_ADDRESS_SERVER_BASIC;
+ lAttributes.handler_type = TAO_ECG_Mcast_Gateway::ECG_HANDLER_UDP;
+ lAttributes.service_type = TAO_ECG_Mcast_Gateway::ECG_MCAST_TWO_WAY;
+
+ TAO_ECG_Mcast_Gateway gateway;
+ if (gateway.init (sub,
+ address_server_arg,
+ lAttributes)
+ == -1)
+ return;
+
+ gateway.run (this->orb_.in (),
+ this->event_channel_.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->allocate_tasks () == -1)
+ return;
+
+ this->activate_tasks (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "BCast (%P|%t) suppliers are active\n"));
+
+ ACE_Time_Value tv (30, 0);
+ this->orb_->run (tv);
+
+ // Wait for the supplier threads...
+ if (ACE_Thread_Manager::instance ()->wait () == -1)
+ {
+ ACE_ERROR ((LM_ERROR, "BCast (%P|%t) Thread_Manager wait failed\n"));
+ }
+}
+
+void
+EC_BCast::dump_results (void)
+{
+ this->EC_Driver::dump_results ();
+}
+
+// ****************************************************************
+
+Simple_Address_Server::
+Simple_Address_Server (const ACE_INET_Addr& address)
+{
+ this->address_.ipaddr = address.get_ip_address ();
+ this->address_.port = address.get_port_number ();
+}
+
+void
+Simple_Address_Server::get_addr (const RtecEventComm::EventHeader&,
+ RtecUDPAdmin::UDP_Addr& address
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ address = this->address_;
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/BCast.h b/TAO/orbsvcs/tests/Event/Basic/BCast.h
new file mode 100644
index 00000000000..3d1b701984a
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/BCast.h
@@ -0,0 +1,85 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file BCast.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan (coryan@cs.wustl.edu)
+ */
+//=============================================================================
+
+
+#ifndef EC_BCAST_H
+#define EC_BCAST_H
+
+#include "Driver.h"
+#include "orbsvcs/RtecUDPAdminS.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+class ACE_INET_Addr;
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class EC_BCast
+ *
+ * @brief Test the EC bcast
+ *
+ */
+class EC_BCast : public EC_Driver
+{
+public:
+ /// Constructor
+ EC_BCast (void);
+
+ // = The EC_Driver methods
+ /// add some command line args to enable/disable bcastions
+ virtual int parse_args (int& argc, char* argv[]);
+ virtual void print_args (void) const;
+ virtual void print_usage (void);
+
+ /// set the bcastion flags
+ virtual void modify_attributes (TAO_EC_Event_Channel_Attributes& attr);
+
+ /// Don't run the suppliers, just test connect and disconnect calls.
+ void execute_test (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Don't dump the EC_Driver results, they are meaningless.
+ void dump_results (void);
+
+private:
+ /// The IP address used to broadcast
+ const char* bcast_address_;
+
+ /// The port used to send and receive bcast messages...
+ u_short bcast_port_;
+};
+
+// ****************************************************************
+
+/**
+ * @class Simple_Address_Server
+ *
+ * A fixed address server
+ */
+class Simple_Address_Server : public POA_RtecUDPAdmin::AddrServer
+{
+public:
+ /// constructo
+ Simple_Address_Server (const ACE_INET_Addr& address);
+
+ virtual void get_addr (const RtecEventComm::EventHeader& header,
+ RtecUDPAdmin::UDP_Addr& address
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+private:
+ /// The UDP addres...
+ RtecUDPAdmin::UDP_Addr address_;
+};
+
+#endif /* EC_BCAST_H */
diff --git a/TAO/orbsvcs/tests/Event/Basic/Bitmask.cpp b/TAO/orbsvcs/tests/Event/Basic/Bitmask.cpp
new file mode 100644
index 00000000000..83ee58c7eb8
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Bitmask.cpp
@@ -0,0 +1,254 @@
+// $Id$
+
+#include "Counting_Consumer.h"
+#include "Counting_Supplier.h"
+
+#include "orbsvcs/Time_Utilities.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+
+ACE_RCSID (EC_Tests,
+ Bitmask,
+ "$Id$")
+
+int
+main (int argc, char* argv[])
+{
+ TAO_EC_Default_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;
+
+ 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;
+
+ // ****************************************************************
+
+ TAO_EC_Event_Channel_Attributes attributes (poa.in (),
+ poa.in ());
+ attributes.consumer_reconnect = 1;
+ attributes.supplier_reconnect = 1;
+
+ TAO_EC_Event_Channel ec_impl (attributes);
+ ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::EventChannel_var event_channel =
+ ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+
+ // ****************************************************************
+
+ // Obtain the consumer admin..
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain the supplier admin..
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ const int milliseconds = 50;
+
+ EC_Counting_Supplier first_supplier;
+
+ first_supplier.activate (consumer_admin.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ first_supplier.connect (supplier_admin.in (),
+ 0x00001111UL,
+ 0x11110000UL,
+ 0x00001111UL,
+ 0x11110000UL
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ EC_Counting_Supplier second_supplier;
+
+ second_supplier.activate (consumer_admin.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ second_supplier.connect (supplier_admin.in (),
+ 0x01100000UL,
+ 0x00000110UL,
+ 0x01100000UL,
+ 0x00000110UL
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Consumer consumer_bitmask_reject ("Consumer/bitmask/reject");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_bitmask (0x00001111, 0x11110000);
+ consumer_qos.start_disjunction_group (1);
+ consumer_qos.insert (0x01100000, 0x00000110, 0);
+
+ consumer_bitmask_reject.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ EC_Counting_Consumer consumer_bitmask_accept ("Consumer/bitmask/accept");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_bitmask (0x01100110, 0x01100110);
+ consumer_qos.insert_null_terminator ();
+
+ consumer_bitmask_accept.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ EC_Counting_Consumer consumer_bitmask_filter ("Consumer/bitmask/filter");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_bitmask (0x00000110, 0x01100000);
+ consumer_qos.insert_null_terminator ();
+
+ consumer_bitmask_filter.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ EC_Counting_Consumer consumer_bitmask_value ("Consumer/bitmask/value");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group (1);
+ consumer_qos.insert_bitmasked_value (0x11110000, 0x00001111,
+ 0x01100000, 0x00000110);
+
+ consumer_bitmask_value.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ EC_Counting_Consumer consumer_bitmask_loose ("Consumer/bitmask/loose");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group (1);
+ consumer_qos.insert_bitmasked_value (0x11111111, 0x11111111,
+ 0x01100000, 0x00000110);
+
+ consumer_bitmask_loose.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ ACE_Time_Value tv (5, 0);
+ // Wait for events, using work_pending()/perform_work() may help
+ // or using another thread, this example is too simple for that.
+ orb->run (tv);
+
+ // ****************************************************************
+
+ consumer_bitmask_loose.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ consumer_bitmask_value.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ consumer_bitmask_filter.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ consumer_bitmask_accept.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ consumer_bitmask_reject.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ second_supplier.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ second_supplier.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ first_supplier.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ first_supplier.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ consumer_bitmask_reject.dump_results (0, 5);
+ CORBA::ULong expected =
+ first_supplier.event_count
+ + second_supplier.event_count;
+ consumer_bitmask_accept.dump_results (expected, 5);
+
+ expected = second_supplier.event_count;
+ consumer_bitmask_filter.dump_results (expected, 5);
+ expected = second_supplier.event_count;
+ consumer_bitmask_value.dump_results (expected, 5);
+ expected = second_supplier.event_count;
+ consumer_bitmask_loose.dump_results (expected, 5);
+
+ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service");
+ return 1;
+ }
+ ACE_ENDTRY;
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/Complex.cpp b/TAO/orbsvcs/tests/Event/Basic/Complex.cpp
new file mode 100644
index 00000000000..5a021eb4e08
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Complex.cpp
@@ -0,0 +1,238 @@
+// $Id$
+
+#include "Counting_Consumer.h"
+#include "Counting_Supplier.h"
+#include "orbsvcs/Time_Utilities.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+
+ACE_RCSID (EC_Tests,
+ Complex,
+ "$Id$")
+
+int
+main (int argc, char* argv[])
+{
+ TAO_EC_Default_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;
+
+ 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;
+
+ // ****************************************************************
+
+ TAO_EC_Event_Channel_Attributes attributes (poa.in (),
+ poa.in ());
+
+ TAO_EC_Event_Channel ec_impl (attributes);
+ ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::EventChannel_var event_channel =
+ ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+
+ // ****************************************************************
+
+ // Obtain the consumer admin..
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain the supplier admin..
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ const int event_type = 20;
+ const int event_source = 10;
+ const int milliseconds = 50;
+
+ EC_Counting_Supplier supplier_00;
+
+ supplier_00.activate (consumer_admin.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier_00.connect (supplier_admin.in (),
+ event_source,
+ event_type,
+ event_source,
+ event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Supplier supplier_01;
+
+ supplier_01.activate (consumer_admin.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier_01.connect (supplier_admin.in (),
+ event_source,
+ event_type + 1,
+ event_source,
+ event_type + 1
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Supplier supplier_10;
+
+ supplier_10.activate (consumer_admin.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier_10.connect (supplier_admin.in (),
+ event_source + 1,
+ event_type,
+ event_source + 1,
+ event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Supplier supplier_11;
+
+ supplier_11.activate (consumer_admin.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier_11.connect (supplier_admin.in (),
+ event_source + 1,
+ event_type + 1,
+ event_source + 1,
+ event_type + 1
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Consumer consumer_00 ("Consumer/00");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_logical_and_group (2);
+ consumer_qos.start_negation ();
+ consumer_qos.insert_source (event_source + 1, 0);
+ consumer_qos.insert_type (event_type, 0);
+
+ consumer_00.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ EC_Counting_Consumer consumer_01 ("Consumer/01");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_logical_and_group (2);
+ consumer_qos.insert_null_terminator (); // Any event
+ consumer_qos.start_negation (); // but for (source,type)
+ consumer_qos.insert (event_source, event_type, 0);
+
+ consumer_01.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ ACE_Time_Value tv (5, 0);
+ // Wait for events, using work_pending()/perform_work() may help
+ // or using another thread, this example is too simple for that.
+ orb->run (tv);
+
+ // ****************************************************************
+
+ consumer_01.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ consumer_00.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ supplier_11.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier_10.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier_01.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier_00.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ supplier_11.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier_10.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier_01.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier_00.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ CORBA::ULong expected =
+ supplier_00.event_count;
+ consumer_00.dump_results (expected, 5);
+
+ expected =
+ supplier_01.event_count
+ + supplier_10.event_count
+ + supplier_11.event_count;
+ consumer_01.dump_results (expected, 5);
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service");
+ return 1;
+ }
+ ACE_ENDTRY;
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/Control.cpp b/TAO/orbsvcs/tests/Event/Basic/Control.cpp
new file mode 100644
index 00000000000..d5e07b61bb9
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Control.cpp
@@ -0,0 +1,205 @@
+// $Id$
+
+#include "Control.h"
+#include "Counting_Supplier.h"
+
+#include "ace/OS_NS_unistd.h"
+
+#include "orbsvcs/Time_Utilities.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+
+ACE_RCSID (EC_Tests,
+ Control,
+ "$Id$")
+
+const int event_type = 20;
+const int event_source = 10;
+
+int
+main (int argc, char* argv[])
+{
+ TAO_EC_Default_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;
+
+ 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;
+
+ // ****************************************************************
+
+ TAO_EC_Event_Channel_Attributes attributes (poa.in (),
+ poa.in ());
+ attributes.consumer_reconnect = 1;
+ attributes.supplier_reconnect = 1;
+
+ TAO_EC_Event_Channel ec_impl (attributes);
+ ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::EventChannel_var event_channel =
+ ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+
+ // ****************************************************************
+
+ // Obtain the consumer admin..
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain the supplier admin..
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Supplier supplier0;
+
+ supplier0.connect (supplier_admin.in (),
+ event_source,
+ event_type,
+ event_source,
+ event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+ Consumer consumer0 ("Consumer/0", 100);
+
+ ACE_ConsumerQOS_Factory consumer_qos0;
+ consumer_qos0.start_disjunction_group ();
+ consumer_qos0.insert (event_source, event_type, 0);
+
+ consumer0.connect (consumer_admin.in (),
+ consumer_qos0.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+ Consumer consumer1 ("Consumer/1", 200);
+
+ consumer1.connect (consumer_admin.in (),
+ consumer_qos0.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Supplier_Task task0 (&supplier0);
+
+ task0.activate ();
+
+ // ****************************************************************
+
+ ACE_Time_Value tv (10, 0);
+ ACE_OS::sleep (tv);
+
+ task0.stop ();
+
+ ACE_Thread_Manager::instance ()->wait ();
+
+ // ****************************************************************
+
+ // Cleanup..
+
+ // The consumers should be disconnected already, but make sure
+ // that they did...
+ //consumer1.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ //ACE_TRY_CHECK;
+ //consumer0.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ //ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ supplier0.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ ACE_DEBUG ((LM_DEBUG,
+ "Task 0 pushed %d events\n", task0.push_count ()));
+ ACE_DEBUG ((LM_DEBUG,
+ "Supplier 0 pushed %d events\n", supplier0.event_count));
+
+ consumer0.dump_results (100, 5);
+ consumer1.dump_results (200, 5);
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service");
+ return 1;
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+// ****************************************************************
+
+Consumer::Consumer (const char* name,
+ int shutdown_count)
+ : EC_Counting_Consumer (name),
+ shutdown_count_ (shutdown_count)
+{
+}
+
+void
+Consumer::push (const RtecEventComm::EventSet& events
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (events.length () == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "%s (%P|%t) no events\n", this->name_));
+ return;
+ }
+
+ {
+ ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock_);
+ this->event_count++;
+
+ if (this->event_count != this->shutdown_count_)
+ return;
+ }
+
+ this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/Control.h b/TAO/orbsvcs/tests/Event/Basic/Control.h
new file mode 100644
index 00000000000..f8e27523603
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Control.h
@@ -0,0 +1,50 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file Control.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan (coryan@cs.wustl.edu)
+ */
+//=============================================================================
+
+
+#ifndef EC_CONTROL_H
+#define EC_CONTROL_H
+
+#include "Counting_Consumer.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class Consumer
+ *
+ * @brief Simple consumer object
+ *
+ */
+class Consumer : public EC_Counting_Consumer
+{
+public:
+ /// Constructor
+ Consumer (const char* name,
+ int event_count);
+
+ // = The RtecEventComm::PushConsumer methods
+
+ virtual void push (const RtecEventComm::EventSet& events
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+private:
+ /// After this number of events the consumer disconnects from the
+ /// event service.
+ CORBA::ULong shutdown_count_;
+
+ /// Synchronize access to the counter
+ TAO_SYNCH_MUTEX lock_;
+};
+
+#endif /* EC_CONTROL_H */
diff --git a/TAO/orbsvcs/tests/Event/Basic/Disconnect.cpp b/TAO/orbsvcs/tests/Event/Basic/Disconnect.cpp
new file mode 100644
index 00000000000..f0a3aafbcae
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Disconnect.cpp
@@ -0,0 +1,223 @@
+// $Id$
+
+#include "Counting_Supplier.h"
+#include "Counting_Consumer.h"
+
+#include "orbsvcs/Time_Utilities.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+
+ACE_RCSID (EC_Tests,
+ Disconnect,
+ "$Id$")
+
+static void run_test (PortableServer::POA_ptr poa,
+ int use_callbacks
+ ACE_ENV_ARG_DECL);
+
+int
+main (int argc, char* argv[])
+{
+ TAO_EC_Default_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;
+
+ 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;
+
+ // ****************************************************************
+
+ run_test (poa.in (), 0 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ run_test (poa.in (), 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service");
+ return 1;
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+// ****************************************************************
+
+void
+deactivate_servant (PortableServer::Servant servant
+ ACE_ENV_ARG_DECL)
+{
+ PortableServer::POA_var poa =
+ servant->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ PortableServer::ObjectId_var id =
+ poa->servant_to_id (servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ poa->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+run_test (PortableServer::POA_ptr poa,
+ int use_callbacks
+ ACE_ENV_ARG_DECL)
+{
+ TAO_EC_Event_Channel_Attributes attributes (poa, poa);
+ attributes.disconnect_callbacks = use_callbacks;
+
+ TAO_EC_Event_Channel ec_impl (attributes);
+ ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ RtecEventChannelAdmin::EventChannel_var event_channel =
+ ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // ****************************************************************
+
+ // Obtain the consumer admin..
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // and the supplier admin..
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // ****************************************************************
+
+ int iterations = 100;
+
+ EC_Counting_Supplier supplier_0;
+ EC_Counting_Supplier supplier_1;
+ EC_Counting_Consumer consumer_0 ("Consumer/0");
+ EC_Counting_Consumer consumer_1 ("Consumer/1");
+
+ const int event_type = 20;
+ const int event_source = 10;
+
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group ();
+ consumer_qos.insert (event_source, event_type, 0);
+
+ ACE_SupplierQOS_Factory supplier_qos;
+ supplier_qos.insert (event_source,
+ event_type,
+ 0, 1);
+
+ for (int i = 0; i != iterations; ++i)
+ {
+ supplier_0.connect (supplier_admin.in (),
+ supplier_qos.get_SupplierQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ consumer_0.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ if (i % 2 == 1)
+ {
+ supplier_1.connect (supplier_admin.in (),
+ supplier_qos.get_SupplierQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ consumer_1.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ supplier_0.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ consumer_0.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ if (i % 2 == 1)
+ {
+ consumer_1.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ supplier_1.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ }
+
+ supplier_0.connect (supplier_admin.in (),
+ supplier_qos.get_SupplierQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ consumer_0.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ deactivate_servant (&supplier_0 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ deactivate_servant (&consumer_0 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ deactivate_servant (&ec_impl ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ CORBA::ULong count_0 = 1;
+ CORBA::ULong count_1 = 0;
+ if (use_callbacks)
+ {
+ count_0 += iterations;
+ count_1 += iterations / 2;
+ }
+
+ if (consumer_0.disconnect_count != count_0)
+ ACE_ERROR ((LM_ERROR,
+ "ERROR: incorrect number of disconnect calls (%d/%d) for "
+ "consumer 0 (%d)\n",
+ consumer_0.disconnect_count, count_0,
+ use_callbacks));
+ if (supplier_0.disconnect_count != count_0)
+ ACE_ERROR ((LM_ERROR,
+ "ERROR: incorrect number of disconnect calls (%d/%d) for "
+ "supplier 0 (%d)\n",
+ supplier_0.disconnect_count, count_0,
+ use_callbacks));
+
+ if (consumer_1.disconnect_count != count_1)
+ ACE_ERROR ((LM_ERROR,
+ "ERROR: incorrect number of disconnect calls (%d/%d) for "
+ "consumer 1 (%d)\n",
+ consumer_1.disconnect_count, count_1,
+ use_callbacks));
+ if (supplier_1.disconnect_count != count_1)
+ ACE_ERROR ((LM_ERROR,
+ "ERROR: incorrect number of disconnect calls (%d/%d) for "
+ "supplier 1 (%d)\n",
+ supplier_1.disconnect_count, count_1,
+ use_callbacks));
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/Event_Basic.mpc b/TAO/orbsvcs/tests/Event/Basic/Event_Basic.mpc
new file mode 100644
index 00000000000..d18e0dd4515
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Event_Basic.mpc
@@ -0,0 +1,93 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Reconnect): rteventtestexe {
+ Source_Files {
+ Reconnect.cpp
+ }
+}
+
+project(*Shutdown): rteventtestexe {
+ Source_Files {
+ Shutdown.cpp
+ }
+}
+
+project(*Observer): rteventtestexe {
+ Source_Files {
+ Observer.cpp
+ }
+}
+
+project(*BCast): rteventtestexe {
+ Source_Files {
+ BCast.cpp
+ }
+}
+
+project(*Timeout): rteventtestexe {
+ Source_Files {
+ Timeout.cpp
+ }
+}
+
+project(*Wildcard): rteventtestexe {
+ Source_Files {
+ Wildcard.cpp
+ }
+}
+
+project(*Negation): rteventtestexe {
+ Source_Files {
+ Negation.cpp
+ }
+}
+
+project(*Disconnect): rteventtestexe {
+ Source_Files {
+ Disconnect.cpp
+ }
+}
+
+project(*MT_Disconnect): rteventtestexe {
+ Source_Files {
+ MT_Disconnect.cpp
+ }
+}
+
+project(*Atomic_Reconnect): rteventtestexe {
+ Source_Files {
+ Atomic_Reconnect.cpp
+ }
+}
+
+project(*Bitmask): rteventtestexe {
+ Source_Files {
+ Bitmask.cpp
+ }
+}
+
+project(*Complex): rteventtestexe {
+ Source_Files {
+ Complex.cpp
+ }
+}
+
+project(*Gateway): rteventtestexe {
+ Source_Files {
+ Gateway.cpp
+ }
+}
+
+project(*Control): rteventtestexe {
+ Source_Files {
+ Control.cpp
+ }
+}
+
+project(*Random) : rteventtestexe {
+ Source_Files {
+ Random.cpp
+ }
+}
+
diff --git a/TAO/orbsvcs/tests/Event/Basic/Gateway.cpp b/TAO/orbsvcs/tests/Event/Basic/Gateway.cpp
new file mode 100644
index 00000000000..39c750d1a4d
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Gateway.cpp
@@ -0,0 +1,359 @@
+// $Id$
+
+#include "Counting_Consumer.h"
+#include "Counting_Supplier.h"
+#include "orbsvcs/Time_Utilities.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+#include "orbsvcs/Event/EC_Gateway_IIOP.h"
+
+ACE_RCSID (EC_Tests,
+ Gateway,
+ "$Id$")
+
+int
+main (int argc, char* argv[])
+{
+ TAO_EC_Default_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;
+
+ 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;
+
+ // ****************************************************************
+
+ TAO_EC_Event_Channel_Attributes attributes (poa.in (),
+ poa.in ());
+ attributes.consumer_reconnect = 1;
+ attributes.supplier_reconnect = 1;
+
+ TAO_EC_Event_Channel ec_impl_1 (attributes);
+ ec_impl_1.activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::EventChannel_var event_channel_1 =
+ ec_impl_1._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ TAO_EC_Event_Channel ec_impl_2 (attributes);
+ ec_impl_2.activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::EventChannel_var event_channel_2 =
+ ec_impl_2._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ // Obtain the consumer admin..
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin_1 =
+ event_channel_1->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain the supplier admin..
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin_1 =
+ event_channel_1->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ // Obtain the consumer admin..
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin_2 =
+ event_channel_2->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain the supplier admin..
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin_2 =
+ event_channel_2->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ TAO_EC_Gateway_IIOP gateway;
+ gateway.init (event_channel_1.in (),
+ event_channel_2.in ()
+ ACE_ENV_ARG_PARAMETER);
+
+ RtecEventChannelAdmin::Observer_var obs =
+ gateway._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::Observer_Handle h =
+ event_channel_2->append_observer (obs.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ gateway.observer_handle (h);
+
+ // ****************************************************************
+
+ const int event_type = 20;
+ const int event_source = 10;
+ const int milliseconds = 50;
+
+ EC_Counting_Supplier supplier_00;
+
+ supplier_00.activate (consumer_admin_1.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier_00.connect (supplier_admin_1.in (),
+ event_source,
+ event_type,
+ event_source,
+ event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ EC_Counting_Supplier supplier_01;
+
+ supplier_01.activate (consumer_admin_1.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier_01.connect (supplier_admin_1.in (),
+ event_source,
+ event_type + 1,
+ event_source,
+ event_type + 1
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Consumer consumer_00 ("Consumer/00");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group (1);
+ consumer_qos.insert (event_source, event_type, 0);
+
+ consumer_00.connect (consumer_admin_2.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ ACE_Time_Value tv (5, 0);
+ // Wait for events, using work_pending()/perform_work() may help
+ // or using another thread, this example is too simple for that.
+ orb->run (tv);
+
+ // ****************************************************************
+
+ CORBA::ULong expected =
+ supplier_00.event_count;
+ consumer_00.dump_results (expected, 5);
+
+ CORBA::ULong last_count = consumer_00.event_count;
+ CORBA::ULong last_supplier_00 = supplier_00.event_count;
+ CORBA::ULong last_supplier_01 = supplier_01.event_count;
+
+ // ****************************************************************
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group (2);
+ consumer_qos.insert (event_source, event_type, 0);
+ consumer_qos.insert (event_source, event_type + 1, 0);
+
+ consumer_00.connect (consumer_admin_2.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ tv = ACE_Time_Value (5, 0);
+ orb->run (tv);
+
+ expected = last_count
+ + supplier_00.event_count - last_supplier_00
+ + supplier_01.event_count - last_supplier_01;
+ consumer_00.dump_results (expected, 5);
+
+ last_count = consumer_00.event_count;
+ last_supplier_00 = supplier_00.event_count;
+ last_supplier_01 = supplier_01.event_count;
+
+ // ****************************************************************
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group (1);
+ consumer_qos.insert (event_source, event_type, 0);
+
+ consumer_00.connect (consumer_admin_2.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ tv = ACE_Time_Value (5, 0);
+ orb->run (tv);
+
+ expected = last_count
+ + supplier_00.event_count - last_supplier_00;
+ consumer_00.dump_results (expected, 5);
+
+ last_count = consumer_00.event_count;
+ last_supplier_00 = supplier_00.event_count;
+ last_supplier_01 = supplier_01.event_count;
+
+ // ****************************************************************
+
+ consumer_00.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group (1);
+ consumer_qos.insert_type (event_type, 0);
+
+ consumer_00.connect (consumer_admin_2.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ tv = ACE_Time_Value (5, 0);
+ // Wait for events, using work_pending()/perform_work() may help
+ // or using another thread, this example is too simple for that.
+ orb->run (tv);
+
+ // ****************************************************************
+
+ expected = last_count
+ + supplier_00.event_count - last_supplier_00;
+ consumer_00.dump_results (expected, 5);
+
+ last_count = consumer_00.event_count;
+ last_supplier_00 = supplier_00.event_count;
+ last_supplier_01 = supplier_01.event_count;
+
+ // ****************************************************************
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group (2);
+ consumer_qos.insert_type (event_type, 0);
+ consumer_qos.insert_type (event_type + 1, 0);
+
+ consumer_00.connect (consumer_admin_2.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ tv = ACE_Time_Value (5, 0);
+ orb->run (tv);
+
+ expected = last_count
+ + supplier_00.event_count - last_supplier_00
+ + supplier_01.event_count - last_supplier_01;
+ consumer_00.dump_results (expected, 5);
+
+ last_count = consumer_00.event_count;
+ last_supplier_00 = supplier_00.event_count;
+ last_supplier_01 = supplier_01.event_count;
+
+ // ****************************************************************
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group (1);
+ consumer_qos.insert_type (event_type, 0);
+
+ consumer_00.connect (consumer_admin_2.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ tv = ACE_Time_Value (5, 0);
+ orb->run (tv);
+
+ expected = last_count
+ + supplier_00.event_count - last_supplier_00;
+ consumer_00.dump_results (expected, 5);
+
+ last_count = consumer_00.event_count;
+ last_supplier_00 = supplier_00.event_count;
+ last_supplier_01 = supplier_01.event_count;
+
+ // ****************************************************************
+
+ consumer_00.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ supplier_01.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier_00.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ supplier_01.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier_00.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ gateway.shutdown (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ event_channel_1->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ event_channel_2->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service");
+ return 1;
+ }
+ ACE_ENDTRY;
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/MT_Disconnect.cpp b/TAO/orbsvcs/tests/Event/Basic/MT_Disconnect.cpp
new file mode 100644
index 00000000000..9f91b760a0a
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/MT_Disconnect.cpp
@@ -0,0 +1,254 @@
+// $Id$
+
+#include "MT_Disconnect.h"
+#include "Counting_Consumer.h"
+#include "Counting_Supplier.h"
+
+#include "orbsvcs/Time_Utilities.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+
+ACE_RCSID (EC_Tests,
+ MT_Disconnect,
+ "$Id$")
+
+static void run_test (PortableServer::POA_ptr poa,
+ int use_callbacks
+ ACE_ENV_ARG_DECL);
+
+int
+main (int argc, char* argv[])
+{
+ TAO_EC_Default_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;
+
+ 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;
+
+ // ****************************************************************
+
+ run_test (poa.in (), 0 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ run_test (poa.in (), 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service");
+ return 1;
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+// ****************************************************************
+
+void
+deactivate_servant (PortableServer::Servant servant
+ ACE_ENV_ARG_DECL)
+{
+ PortableServer::POA_var poa =
+ servant->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ PortableServer::ObjectId_var id =
+ poa->servant_to_id (servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ poa->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+run_test (PortableServer::POA_ptr poa,
+ int use_callbacks
+ ACE_ENV_ARG_DECL)
+{
+ TAO_EC_Event_Channel_Attributes attributes (poa, poa);
+ attributes.disconnect_callbacks = use_callbacks;
+
+ TAO_EC_Event_Channel ec_impl (attributes);
+ ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ RtecEventChannelAdmin::EventChannel_var event_channel =
+ ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ Task task (event_channel.in (), use_callbacks);
+
+ if (task.activate (THR_BOUND|THR_NEW_LWP, 1) != 0)
+ {
+ ACE_ERROR ((LM_ERROR, "Cannot activate the tasks\n"));
+ }
+
+ // Wait for all the threads to complete and the return
+ ACE_Thread_Manager::instance ()->wait ();
+
+ event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ deactivate_servant (&ec_impl ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+Task::Task (RtecEventChannelAdmin::EventChannel_ptr ec,
+ int callbacks)
+ : event_channel (RtecEventChannelAdmin::EventChannel::_duplicate (ec)),
+ use_callbacks (callbacks)
+{
+}
+
+
+int
+Task::svc ()
+{
+ for (int i = 0; i < 10; ++i)
+ {
+ ACE_TRY_NEW_ENV
+ {
+ this->run_iteration (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ return -1;
+ }
+ ACE_ENDTRY;
+ }
+ return 0;
+}
+
+void
+Task::run_iteration (ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Obtain the consumer admin..
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ this->event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // and the supplier admin..
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ this->event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // ****************************************************************
+
+ int iterations = 100;
+
+ EC_Counting_Supplier supplier_0;
+ EC_Counting_Supplier supplier_1;
+ EC_Counting_Consumer consumer_0 ("Consumer/0");
+ EC_Counting_Consumer consumer_1 ("Consumer/1");
+
+ const int event_type = 20;
+ const int event_source = 10;
+
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group ();
+ consumer_qos.insert (event_source, event_type, 0);
+
+ ACE_SupplierQOS_Factory supplier_qos;
+ supplier_qos.insert (event_source,
+ event_type,
+ 0, 1);
+
+ for (int i = 0; i != iterations; ++i)
+ {
+ supplier_0.connect (supplier_admin.in (),
+ supplier_qos.get_SupplierQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ consumer_0.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ if (i % 2 == 1)
+ {
+ supplier_1.connect (supplier_admin.in (),
+ supplier_qos.get_SupplierQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ consumer_1.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ supplier_0.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ consumer_0.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ if (i % 2 == 1)
+ {
+ consumer_1.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ supplier_1.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ }
+
+ deactivate_servant (&supplier_0 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ deactivate_servant (&consumer_0 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ CORBA::ULong count_0 = 0;
+ CORBA::ULong count_1 = 0;
+ if (use_callbacks)
+ {
+ count_0 += iterations;
+ count_1 += iterations / 2;
+ }
+
+ if (consumer_0.disconnect_count != count_0)
+ ACE_ERROR ((LM_ERROR,
+ "ERROR: incorrect number of disconnect calls (%d/%d) for "
+ "consumer 0 (%d)\n",
+ consumer_0.disconnect_count, count_0,
+ use_callbacks));
+ if (supplier_0.disconnect_count != count_0)
+ ACE_ERROR ((LM_ERROR,
+ "ERROR: incorrect number of disconnect calls (%d/%d) for "
+ "supplier 0 (%d)\n",
+ supplier_0.disconnect_count, count_0,
+ use_callbacks));
+
+ if (consumer_1.disconnect_count != count_1)
+ ACE_ERROR ((LM_ERROR,
+ "ERROR: incorrect number of disconnect calls (%d/%d) for "
+ "consumer 1 (%d)\n",
+ consumer_1.disconnect_count, count_1,
+ use_callbacks));
+ if (supplier_1.disconnect_count != count_1)
+ ACE_ERROR ((LM_ERROR,
+ "ERROR: incorrect number of disconnect calls (%d/%d) for "
+ "supplier 1 (%d)\n",
+ supplier_1.disconnect_count, count_1,
+ use_callbacks));
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/MT_Disconnect.h b/TAO/orbsvcs/tests/Event/Basic/MT_Disconnect.h
new file mode 100644
index 00000000000..06855260d66
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/MT_Disconnect.h
@@ -0,0 +1,45 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file MT_Disconnect.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan (coryan@cs.wustl.edu)
+ */
+//=============================================================================
+
+
+#ifndef EC_MT_DISCONNECT_H
+#define EC_MT_DISCONNECT_H
+
+#include "ace/Task.h"
+#include "orbsvcs/RtecEventChannelAdminC.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class Task : public ACE_Task_Base
+{
+public:
+ /// Create the task...
+ Task (RtecEventChannelAdmin::EventChannel_ptr ec,
+ int use_callbacks);
+
+ // = Check the ACE_Task_Base documentation.
+ int svc (void);
+
+ /// Run a single iteration of the test
+ void run_iteration (ACE_ENV_SINGLE_ARG_DECL);
+
+private:
+ /// The event channel used on the test
+ RtecEventChannelAdmin::EventChannel_var event_channel;
+
+ /// Does the event channel send any callback messages when a client
+ /// diconnects
+ int use_callbacks;
+};
+
+#endif /* EC_DISCONNECT_H */
diff --git a/TAO/orbsvcs/tests/Event/Basic/Makefile.am b/TAO/orbsvcs/tests/Event/Basic/Makefile.am
new file mode 100644
index 00000000000..b68828bdc89
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Makefile.am
@@ -0,0 +1,680 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## ../bin/mwc.pl -type automake -noreldefs TAO.mwc
+
+ACE_BUILDDIR = $(top_builddir)/..
+ACE_ROOT = $(top_srcdir)/..
+TAO_BUILDDIR = $(top_builddir)
+TAO_ROOT = $(top_srcdir)
+
+noinst_PROGRAMS =
+
+## Makefile.Event_Basic_Atomic_Reconnect.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Atomic_Reconnect
+
+Atomic_Reconnect_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Atomic_Reconnect_SOURCES = \
+ Atomic_Reconnect.cpp \
+ Atomic_Reconnect.h
+
+Atomic_Reconnect_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Basic_BCast.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += BCast
+
+BCast_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+BCast_SOURCES = \
+ BCast.cpp \
+ BCast.h
+
+BCast_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Basic_Bitmask.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Bitmask
+
+Bitmask_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Bitmask_SOURCES = \
+ Bitmask.cpp \
+ Atomic_Reconnect.h \
+ BCast.h \
+ Control.h \
+ MT_Disconnect.h \
+ Observer.h \
+ Random.h \
+ Reconnect.h \
+ Schedule.h \
+ Shutdown.h
+
+Bitmask_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Basic_Complex.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Complex
+
+Complex_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Complex_SOURCES = \
+ Complex.cpp \
+ Atomic_Reconnect.h \
+ BCast.h \
+ Control.h \
+ MT_Disconnect.h \
+ Observer.h \
+ Random.h \
+ Reconnect.h \
+ Schedule.h \
+ Shutdown.h
+
+Complex_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Basic_Control.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Control
+
+Control_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Control_SOURCES = \
+ Control.cpp \
+ Control.h
+
+Control_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Basic_Disconnect.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Disconnect
+
+Disconnect_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Disconnect_SOURCES = \
+ Disconnect.cpp \
+ Atomic_Reconnect.h \
+ BCast.h \
+ Control.h \
+ MT_Disconnect.h \
+ Observer.h \
+ Random.h \
+ Reconnect.h \
+ Schedule.h \
+ Shutdown.h
+
+Disconnect_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Basic_Gateway.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Gateway
+
+Gateway_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Gateway_SOURCES = \
+ Gateway.cpp \
+ Atomic_Reconnect.h \
+ BCast.h \
+ Control.h \
+ MT_Disconnect.h \
+ Observer.h \
+ Random.h \
+ Reconnect.h \
+ Schedule.h \
+ Shutdown.h
+
+Gateway_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Basic_MT_Disconnect.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += MT_Disconnect
+
+MT_Disconnect_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+MT_Disconnect_SOURCES = \
+ MT_Disconnect.cpp \
+ MT_Disconnect.h
+
+MT_Disconnect_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Basic_Negation.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Negation
+
+Negation_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Negation_SOURCES = \
+ Negation.cpp \
+ Atomic_Reconnect.h \
+ BCast.h \
+ Control.h \
+ MT_Disconnect.h \
+ Observer.h \
+ Random.h \
+ Reconnect.h \
+ Schedule.h \
+ Shutdown.h
+
+Negation_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Basic_Observer.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Observer
+
+Observer_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Observer_SOURCES = \
+ Observer.cpp \
+ Observer.h
+
+Observer_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Basic_Random.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Random
+
+Random_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Random_SOURCES = \
+ Random.cpp \
+ Random.h
+
+Random_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Basic_Reconnect.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Reconnect
+
+Reconnect_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Reconnect_SOURCES = \
+ Reconnect.cpp \
+ Reconnect.h
+
+Reconnect_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Basic_Shutdown.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Shutdown
+
+Shutdown_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Shutdown_SOURCES = \
+ Shutdown.cpp \
+ Shutdown.h
+
+Shutdown_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Basic_Timeout.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Timeout
+
+Timeout_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Timeout_SOURCES = \
+ Timeout.cpp \
+ Atomic_Reconnect.h \
+ BCast.h \
+ Control.h \
+ MT_Disconnect.h \
+ Observer.h \
+ Random.h \
+ Reconnect.h \
+ Schedule.h \
+ Shutdown.h
+
+Timeout_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Basic_Wildcard.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Wildcard
+
+Wildcard_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Wildcard_SOURCES = \
+ Wildcard.cpp \
+ Atomic_Reconnect.h \
+ BCast.h \
+ Control.h \
+ MT_Disconnect.h \
+ Observer.h \
+ Random.h \
+ Reconnect.h \
+ Schedule.h \
+ Shutdown.h
+
+Wildcard_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/TAO/orbsvcs/tests/Event/Basic/Negation.cpp b/TAO/orbsvcs/tests/Event/Basic/Negation.cpp
new file mode 100644
index 00000000000..37ab5c1fb30
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Negation.cpp
@@ -0,0 +1,214 @@
+// $Id$
+
+#include "Counting_Consumer.h"
+#include "Counting_Supplier.h"
+
+#include "orbsvcs/Time_Utilities.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+
+ACE_RCSID (EC_Tests,
+ Negation,
+ "$Id$")
+
+int
+main (int argc, char* argv[])
+{
+ TAO_EC_Default_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;
+
+ 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;
+
+ // ****************************************************************
+
+ TAO_EC_Event_Channel_Attributes attributes (poa.in (),
+ poa.in ());
+ attributes.consumer_reconnect = 1;
+ attributes.supplier_reconnect = 1;
+
+ TAO_EC_Event_Channel ec_impl (attributes);
+ ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::EventChannel_var event_channel =
+ ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+
+ // ****************************************************************
+
+ // Obtain the consumer admin..
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain the supplier admin..
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ const int event_type = 20;
+ const int event_source = 10;
+ const int milliseconds = 50;
+
+ EC_Counting_Supplier first_supplier;
+
+ first_supplier.activate (consumer_admin.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ first_supplier.connect (supplier_admin.in (),
+ event_source,
+ event_type,
+ event_source,
+ event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ EC_Counting_Supplier second_supplier;
+
+ second_supplier.activate (consumer_admin.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ second_supplier.connect (supplier_admin.in (),
+ event_source,
+ event_type + 1,
+ event_source,
+ event_type + 1
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ EC_Counting_Supplier third_supplier;
+
+ third_supplier.activate (consumer_admin.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ third_supplier.connect (supplier_admin.in (),
+ event_source,
+ event_type + 1,
+ event_source,
+ event_type + 1
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Consumer regular_consumer ("Consumer/regular");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group ();
+ consumer_qos.insert (event_source, event_type, 0);
+
+ regular_consumer.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ EC_Counting_Consumer negation_consumer ("Consumer/negation");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_negation ();
+ consumer_qos.start_disjunction_group ();
+ consumer_qos.insert (event_source, event_type, 0);
+
+ negation_consumer.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ ACE_Time_Value tv (5, 0);
+ // Wait for events, using work_pending()/perform_work() may help
+ // or using another thread, this example is too simple for that.
+ orb->run (tv);
+
+ // ****************************************************************
+
+ negation_consumer.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ regular_consumer.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ third_supplier.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ third_supplier.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ second_supplier.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ second_supplier.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ first_supplier.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ first_supplier.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ CORBA::ULong expected =
+ third_supplier.event_count
+ + second_supplier.event_count;
+ negation_consumer.dump_results (expected, 5);
+ expected =
+ first_supplier.event_count;
+ regular_consumer.dump_results (expected, 5);
+
+ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service");
+ return 1;
+ }
+ ACE_ENDTRY;
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/Observer.cpp b/TAO/orbsvcs/tests/Event/Basic/Observer.cpp
new file mode 100644
index 00000000000..d58d828573f
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Observer.cpp
@@ -0,0 +1,415 @@
+// $Id$
+
+#include "Observer.h"
+#include "Consumer.h"
+#include "Supplier.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+#include "ace/Arg_Shifter.h"
+#include "ace/High_Res_Timer.h"
+
+ACE_RCSID (EC_Tests_Basic,
+ Observer,
+ "$Id$")
+
+int
+main (int argc, char *argv [])
+{
+ TAO_EC_Default_Factory::init_svcs ();
+ EC_Master master;
+ return master.run (argc, argv);
+}
+
+// ****************************************************************
+
+EC_Master::EC_Master (void)
+ : seed_ (0),
+ n_channels_ (4),
+ channels_ (0)
+{
+}
+
+EC_Master::~EC_Master (void)
+{
+ if (this->channels_ != 0)
+ {
+ for (int i = 0; i < this->n_channels_; ++i)
+ delete this->channels_[i];
+ delete[] this->channels_;
+ }
+}
+
+int
+EC_Master::run (int argc, char* argv[])
+{
+ ACE_TRY_NEW_ENV
+ {
+ // Calibrate the high resolution timer *before* starting the
+ // test.
+ ACE_High_Res_Timer::calibrate ();
+
+ this->seed_ = ACE_OS::time (0);
+
+ this->initialize_orb_and_poa (argc, argv ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (this->parse_args (argc, argv))
+ return 1;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "The seed value is %d\n", this->seed_));
+
+ ACE_NEW_RETURN (this->channels_,
+ EC_Observer*[this->n_channels_],
+ 1);
+
+ {
+ for (int i = 0; i != this->n_channels_; ++i)
+ {
+ ACE_OS::rand_r (this->seed_);
+ ACE_NEW_RETURN (this->channels_[i],
+ EC_Observer (this,
+ this->seed_,
+ this->orb_.in (),
+ this->root_poa_.in (),
+ i),
+ 1);
+ }
+ }
+
+ {
+ char** targv;
+ ACE_NEW_RETURN (targv, char*[argc], 1);
+
+ for (int i = 0; i != this->n_channels_; ++i)
+ {
+ int targc = argc;
+ for (int j = 0; j < targc; ++j)
+ targv[j] = argv[j];
+ this->channels_[i]->run_init (targc, targv ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ delete[] targv;
+ }
+
+ {
+ for (int i = 0; i != this->n_channels_; ++i)
+ {
+ this->channels_[i]->execute_test (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ }
+
+ if (ACE_Thread_Manager::instance ()->wait () == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "EC_Master (%P|%t) thread manager wait failed\n"));
+ return 1;
+ }
+
+ {
+ for (int i = 0; i != this->n_channels_; ++i)
+ {
+ this->channels_[i]->dump_results ();
+ }
+ }
+
+ {
+ for (int i = 0; i != this->n_channels_; ++i)
+ {
+ this->channels_[i]->run_cleanup (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ }
+
+ {
+ for (int i = 0; i != this->n_channels_; ++i)
+ {
+ this->channels_[i]->disconnect_clients (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ this->channels_[i]->shutdown_clients (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ this->channels_[i]->destroy_ec (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ this->channels_[i]->deactivate_ec (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ this->channels_[i]->cleanup_tasks ();
+ this->channels_[i]->cleanup_suppliers ();
+ this->channels_[i]->cleanup_consumers ();
+ this->channels_[i]->cleanup_ec ();
+ }
+ }
+
+ this->root_poa_->destroy (1,
+ 1
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->orb_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "EC_Driver::run");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR ((LM_ERROR, "EC_Driver (%P|%t) non-corba exception raised\n"));
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+void
+EC_Master::initialize_orb_and_poa (int &argc, char* argv[]
+ ACE_ENV_ARG_DECL)
+{
+ this->orb_ =
+ CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ CORBA::Object_var poa_object =
+ this->orb_->resolve_initial_references("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (CORBA::is_nil (poa_object.in ()))
+ {
+ ACE_ERROR ((LM_ERROR,
+ "EC_Driver (%P|%t) Unable to initialize the POA.\n"));
+ return;
+ }
+
+ this->root_poa_ =
+ PortableServer::POA::_narrow (poa_object.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ PortableServer::POAManager_var poa_manager =
+ this->root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+int
+EC_Master::parse_args (int &argc, char *argv [])
+{
+ ACE_Arg_Shifter arg_shifter (argc, argv);
+
+ while (arg_shifter.is_anything_left ())
+ {
+ const char *arg = arg_shifter.get_current ();
+
+ if (ACE_OS::strcmp (arg, "-channels") == 0)
+ {
+ arg_shifter.consume_arg ();
+ this->n_channels_ = ACE_OS::atoi (arg_shifter.get_current ());
+ }
+ else if (ACE_OS::strcmp (arg, "-seed") == 0)
+ {
+ arg_shifter.consume_arg ();
+ this->seed_ = ACE_OS::atoi (arg_shifter.get_current ());
+ }
+
+ arg_shifter.ignore_arg ();
+ }
+ return 0;
+}
+
+int
+EC_Master::channel_count (void) const
+{
+ return this->n_channels_;
+}
+
+EC_Observer*
+EC_Master::channel (int i) const
+{
+ return this->channels_[i];
+}
+
+// ****************************************************************
+
+EC_Observer::EC_Observer (EC_Master *master,
+ ACE_RANDR_TYPE seed,
+ CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr root_poa,
+ int id)
+ : master_ (master),
+ seed_ (seed),
+ id_ (id),
+ gwys_ (0)
+{
+ this->orb_ = CORBA::ORB::_duplicate (orb);
+ this->root_poa_ = PortableServer::POA::_duplicate (root_poa);
+}
+
+EC_Observer::~EC_Observer (void)
+{
+ if (this->gwys_ != 0)
+ delete[] this->gwys_;
+}
+
+void
+EC_Observer::initialize_orb_and_poa (int&, char*[]
+ ACE_ENV_ARG_DECL_NOT_USED)
+{
+}
+
+int
+EC_Observer::parse_args (int& argc, char* argv[])
+{
+ return this->EC_Driver::parse_args (argc, argv);
+}
+
+void
+EC_Observer::print_args (void) const
+{
+ this->EC_Driver::print_args ();
+}
+
+void
+EC_Observer::print_usage (void)
+{
+ this->EC_Driver::print_usage ();
+}
+
+void
+EC_Observer::execute_test (ACE_ENV_SINGLE_ARG_DECL)
+{
+ int peer_count = this->master_->channel_count ();
+ ACE_NEW (this->gwys_, TAO_EC_Gateway_IIOP[peer_count]);
+
+ for (int i = 0; i != peer_count; ++i)
+ {
+ if (i == this->id_)
+ continue;
+
+ RtecEventChannelAdmin::EventChannel_ptr rmt_ec =
+ this->master_->channel (i)->event_channel_.in ();
+
+ this->gwys_[i].init (rmt_ec,
+ this->event_channel_.in ()
+ ACE_ENV_ARG_PARAMETER);
+
+ RtecEventChannelAdmin::Observer_var obs =
+ this->gwys_[i]._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ RtecEventChannelAdmin::Observer_Handle h =
+ rmt_ec->append_observer (obs.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->gwys_[i].observer_handle (h);
+
+ ACE_CHECK;
+ }
+
+ if (this->allocate_tasks () == -1)
+ return;
+
+ this->activate_tasks (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Observer[%d] (%P|%t) suppliers are active\n",
+ this->id_));
+}
+
+void
+EC_Observer::run_cleanup (ACE_ENV_SINGLE_ARG_DECL)
+{
+ for (int j = 0; j != this->master_->channel_count (); ++j)
+ {
+ if (j == this->id_)
+ continue;
+
+ RtecEventChannelAdmin::EventChannel_ptr rmt_ec =
+ this->master_->channel (j)->event_channel_.in ();
+ rmt_ec->remove_observer (this->gwys_[j].observer_handle ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->gwys_[j].shutdown (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+}
+
+void
+EC_Observer::dump_results (void)
+{
+ ACE_DEBUG ((LM_DEBUG, "===== Results for %d =====\n", this->id_));
+
+ ACE_Throughput_Stats throughput;
+ ACE_UINT32 gsf = ACE_High_Res_Timer::global_scale_factor ();
+ for (int j = 0; j < this->n_consumers_; ++j)
+ {
+ this->consumers_[j]->accumulate (throughput);
+ }
+ ACE_DEBUG ((LM_DEBUG, "\n"));
+
+ ACE_Throughput_Stats suppliers;
+ for (int i = 0; i < this->n_suppliers_; ++i)
+ {
+ this->suppliers_[i]->accumulate (suppliers);
+ }
+
+ ACE_DEBUG ((LM_DEBUG, "\nTotals:\n"));
+ throughput.dump_results ("EC_Consumer/totals", gsf);
+
+ ACE_DEBUG ((LM_DEBUG, "\n"));
+ suppliers.dump_results ("EC_Supplier/totals", gsf);
+}
+
+void
+EC_Observer::connect_consumer (
+ RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin,
+ int i
+ ACE_ENV_ARG_DECL)
+{
+ if (i == 0)
+ {
+ this->EC_Driver::connect_consumer (consumer_admin, i
+ ACE_ENV_ARG_PARAMETER);
+ return;
+ }
+ unsigned int x = ACE_OS::rand_r (this->seed_);
+ if (x < RAND_MAX / 8)
+ this->EC_Driver::connect_consumer (consumer_admin, i
+ ACE_ENV_ARG_PARAMETER);
+}
+
+void
+EC_Observer::consumer_push (void*,
+ const RtecEventComm::EventSet&
+ ACE_ENV_ARG_DECL)
+{
+ unsigned int x = ACE_OS::rand_r (this->seed_);
+ if (x < (RAND_MAX / 64))
+ {
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG,
+ "EC_Observer[%d] (%P|%t) reconnecting\n", this->id_));
+
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ this->event_channel_->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ for (int i = 1; i < this->n_consumers_; ++i)
+ {
+ ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock_);
+
+ if (this->consumers_[i]->connected ())
+ {
+ this->consumers_[i]->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ else
+ {
+ this->EC_Driver::connect_consumer (consumer_admin.in (),
+ i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ }
+ }
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/Observer.h b/TAO/orbsvcs/tests/Event/Basic/Observer.h
new file mode 100644
index 00000000000..bb788c01258
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Observer.h
@@ -0,0 +1,120 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file Observer.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan (coryan@cs.wustl.edu)
+ */
+//=============================================================================
+
+
+#ifndef EC_OBSERVER_H
+#define EC_OBSERVER_H
+
+#include "Driver.h"
+#include "orbsvcs/Event/EC_Gateway_IIOP.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class EC_Observer;
+
+/**
+ * @class EC_Master
+ *
+ * @brief Run multiple events channels
+ *
+ * This test runs multiple event channels, all connected using
+ * gateways.
+ */
+class EC_Master
+{
+public:
+ EC_Master (void);
+
+ virtual ~EC_Master (void);
+
+ /// Execute the test.
+ virtual int run (int argc, char* argv[]);
+
+ /// Obtain the orb and the poa pointers
+ virtual void initialize_orb_and_poa (int& argc, char* argv[]
+ ACE_ENV_ARG_DECL);
+
+ /// Accessors
+ int channel_count (void) const;
+ EC_Observer* channel (int i) const;
+
+private:
+ int parse_args (int &argc, char *argv []);
+
+private:
+ /// The seed
+ ACE_RANDR_TYPE seed_;
+
+ /// The driver programs
+ int n_channels_;
+ EC_Observer** channels_;
+
+ /// The ORB
+ CORBA::ORB_var orb_;
+
+ /// The Root POA
+ PortableServer::POA_var root_poa_;
+};
+
+/**
+ * @class EC_Observer
+ *
+ * @brief Test the EC observers
+ *
+ */
+class EC_Observer : public EC_Driver
+{
+public:
+ /// Constructor
+ EC_Observer (EC_Master *master,
+ ACE_RANDR_TYPE seed,
+ CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr root_poa,
+ int id);
+
+ /// Destructor
+ ~EC_Observer (void);
+
+ // = The EC_Driver methods
+ /// add some command line args to enable/disable observerions
+ virtual void initialize_orb_and_poa (int& argc, char* argv[]
+ ACE_ENV_ARG_DECL);
+ virtual int parse_args (int& argc, char* argv[]);
+ virtual void print_args (void) const;
+ virtual void print_usage (void);
+
+ /// Run the suppliers, using the <thread_manager> parameter
+ void execute_test (ACE_ENV_SINGLE_ARG_DECL);
+ void run_cleanup (ACE_ENV_SINGLE_ARG_DECL);
+
+ void dump_results (void);
+ void connect_consumer (
+ RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin,
+ int i
+ ACE_ENV_ARG_DECL);
+ void consumer_push (void*,
+ const RtecEventComm::EventSet&
+ ACE_ENV_ARG_DECL);
+
+private:
+ EC_Master *master_;
+ ACE_RANDR_TYPE seed_;
+ int id_;
+
+ TAO_EC_Gateway_IIOP *gwys_;
+
+ /// lock internal state
+ TAO_SYNCH_MUTEX lock_;
+};
+
+#endif /* EC_OBSERVER_H */
diff --git a/TAO/orbsvcs/tests/Event/Basic/README b/TAO/orbsvcs/tests/Event/Basic/README
new file mode 100644
index 00000000000..26408823b69
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/README
@@ -0,0 +1,43 @@
+# $Id$
+
+ Basic tests for the real-time event channel.
+
+This directory contains several tests to exercise the real-time event
+channel features, debug it and stress test it. The tests are as simple
+as possible, but not simpler.
+
+ Here are some canonical test configurations:
+
+# Connect 100 suppliers, 100 consumers. Then disconnect and connect
+# one particular consumer, 100. Then do the same for one supplier
+
+$ Reconnect -verbose -suppliers 100 -consumers 100 -d 100
+
+# Same as above, but instead of disconnecting and connecting again
+# simply reconnect. Should be faster
+$ Reconnect -verbose -suppliers 100 -consumers 100 -d 100 -c -s
+
+# Connect 10 suppliers, 10 consumers and then shutdown the EC
+$ Shutdown -verbose -suppliers 5 -consumer 5
+
+# Create 4 event channels, connect all of them using IIOP gateways,
+# then attach 5 consumers and 2 supplier to each, next generate 10000
+# events (each supplier on its own thread). It randomly connect and
+# disconnects the consumers, hence the gateways also do.
+
+$ Observer -ORBsvcconf observer.conf \
+ -consumer_tshift 0 -supplier_tshift 0 \
+ -suppliers 2 -consumers 5 \
+ -channels 4 -burstsize 1000 -burstcount 10 \
+ -burstpause 0 -busyhwm 1024 -maxwritedelay 1024
+
+# Create an event channel in a configuration that informs the
+# scheduler of the dependencies between consumers and suppliers.
+# THIS IS WORK IN PROGRESS
+
+$ Schedule -ORBsvcconf sched.conf -suppliers 5 -consumers 5
+
+NOTES
+
+ Don't worry about the "incomplete data" warning, it is a
+deffect in the test.
diff --git a/TAO/orbsvcs/tests/Event/Basic/Random.cpp b/TAO/orbsvcs/tests/Event/Basic/Random.cpp
new file mode 100644
index 00000000000..b9397f997ed
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Random.cpp
@@ -0,0 +1,578 @@
+// $Id$
+
+#include "Random.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Time_Utilities.h"
+#include "ace/Arg_Shifter.h"
+#include "ace/OS_NS_strings.h"
+#include "ace/OS_NS_unistd.h"
+
+ACE_RCSID (EC_Tests,
+ Random,
+ "$Id$")
+
+int
+main (int argc, char* argv[])
+{
+ RND_Driver driver;
+ return driver.run (argc, argv);
+}
+
+// ****************************************************************
+
+const int base_type = 20;
+
+void
+deactivate_servant (PortableServer::Servant servant
+ ACE_ENV_ARG_DECL)
+{
+ PortableServer::POA_var poa =
+ servant->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ PortableServer::ObjectId_var oid =
+ poa->servant_to_id (servant ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ poa->deactivate_object (oid.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+
+RND_Driver::RND_Driver (void)
+ : timer_ (this),
+ supplier_ (0),
+ nsuppliers_ (4),
+ nconsumers_ (4),
+ max_recursion_ (1),
+ verbose_ (0)
+{
+ TAO_EC_Default_Factory::init_svcs ();
+}
+
+int
+RND_Driver::run (int argc, char *argv[])
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ ACE_Arg_Shifter arg_shifter (argc, argv);
+
+ while (arg_shifter.is_anything_left ())
+ {
+ const char *arg = arg_shifter.get_current ();
+
+ if (ACE_OS::strcasecmp (arg, "-suppliers") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ const char* opt = arg_shifter.get_current ();
+ int n = ACE_OS::atoi (opt);
+ if (n >= 1)
+ this->nsuppliers_ = n;
+ arg_shifter.consume_arg ();
+ }
+ }
+ else if (ACE_OS::strcasecmp (arg, "-consumers") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ const char* opt = arg_shifter.get_current ();
+ int n = ACE_OS::atoi (opt);
+ if (n >= 1)
+ this->nconsumers_ = n;
+ arg_shifter.consume_arg ();
+ }
+ }
+ else if (ACE_OS::strcasecmp (arg, "-max_recursion") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ const char* opt = arg_shifter.get_current ();
+ int n = ACE_OS::atoi (opt);
+ if (n >= 0)
+ this->max_recursion_ = n;
+ arg_shifter.consume_arg ();
+ }
+ }
+ else if (ACE_OS::strcasecmp (arg, "-verbose") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ this->verbose_ = 1;
+ }
+ else
+ arg_shifter.ignore_arg ();
+ }
+
+ // ****************************************************************
+
+ 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;
+
+ // ****************************************************************
+
+ TAO_EC_Event_Channel_Attributes attributes (poa.in (),
+ poa.in ());
+ attributes.consumer_reconnect = 1;
+ attributes.supplier_reconnect = 1;
+
+ TAO_EC_Event_Channel ec_impl (attributes);
+ ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::EventChannel_var event_channel =
+ ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ // Obtain the consumer admin..
+ this->consumer_admin_ =
+ event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain the supplier admin..
+ this->supplier_admin_ =
+ event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ {
+ // Let's say that the execution time for event 2 is 1
+ // milliseconds...
+ ACE_Time_Value tv (0, 50000);
+ TimeBase::TimeT time;
+ ORBSVCS_Time::Time_Value_to_TimeT (time, tv);
+
+ ACE_ConsumerQOS_Factory qos;
+ qos.start_disjunction_group ();
+ // The types int the range [0,ACE_ES_EVENT_UNDEFINED) are
+ // reserved for the EC...
+ qos.insert_time (ACE_ES_EVENT_INTERVAL_TIMEOUT,
+ time,
+ 0);
+
+ this->timer_.connect (this->consumer_admin_.in (),
+ qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ {
+ ACE_SupplierQOS_Factory qos;
+ qos.insert (0, base_type, 0, 1);
+
+ this->supplier_.connect (this->supplier_admin_.in (),
+ qos.get_SupplierQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ ACE_NEW_RETURN (this->consumers_,
+ RND_Consumer*[this->nconsumers_],
+ 1);
+ for (int i = 0; i != this->nconsumers_; ++i)
+ {
+ ACE_NEW_RETURN (this->consumers_[i],
+ RND_Consumer (this),
+ 1);
+
+ CORBA::Object_var obj =
+ this->consumers_[i]->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ ACE_NEW_RETURN (this->suppliers_,
+ RND_Supplier*[this->nsuppliers_],
+ 1);
+ for (int j = 0; j != this->nsuppliers_; ++j)
+ {
+ ACE_NEW_RETURN (this->suppliers_[j],
+ RND_Supplier (this->verbose_),
+ 1);
+ this->suppliers_[j]->activate ();
+
+ CORBA::Object_var obj =
+ this->suppliers_[j]->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ ACE_Time_Value tv (30, 0);
+ orb->run (tv);
+
+ ACE_Thread_Manager::instance ()->wait ();
+
+ // ****************************************************************
+
+ {
+ for (int k = 0; k != this->nsuppliers_; ++k)
+ {
+ deactivate_servant (this->suppliers_[k]
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ this->suppliers_[k]->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ delete[] this->suppliers_;
+ this->suppliers_ = 0;
+ }
+
+ // ****************************************************************
+
+ // We destroy now to verify that the callbacks work and do not
+ // produce any problems.
+ event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ {
+ for (int k = 0; k != this->nconsumers_; ++k)
+ {
+ deactivate_servant (this->consumers_[k]
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ this->consumers_[k]->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ delete[] this->consumers_;
+ this->consumers_ = 0;
+ }
+
+ // ****************************************************************
+
+ deactivate_servant (&ec_impl
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Random");
+ return 1;
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+void
+RND_Driver::timer (const RtecEventComm::Event &e
+ ACE_ENV_ARG_DECL)
+{
+ int r = ACE_OS::rand ();
+ if (r < 0)
+ r = -r;
+
+ int n = r% 20;
+
+ switch (n)
+ {
+ case 0:
+ case 1:
+ {
+ // ACE_DEBUG ((LM_DEBUG, "Pushing an event\n"));
+ if (e.header.source < this->max_recursion_)
+ {
+ RtecEventComm::EventSet event (1);
+ event.length (1);
+ event[0] = e;
+ event[0].header.source ++;
+ this->supplier_.push (event ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ }
+ break;
+
+ default:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ // ACE_DEBUG ((LM_DEBUG, "Received event\n"));
+ break;
+
+ case 6:
+ {
+ int n = ACE_OS::rand () % this->nsuppliers_;
+
+ // ACE_DEBUG ((LM_DEBUG, "Connecting supplier %d\n", n));
+
+ ACE_SupplierQOS_Factory qos;
+ qos.insert (0, base_type, 0, 1);
+
+ this->suppliers_[n]->connect (this->supplier_admin_.in (),
+ qos.get_SupplierQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ break;
+
+ case 7:
+ {
+ int n = ACE_OS::rand () % this->nconsumers_;
+
+ // ACE_DEBUG ((LM_DEBUG, "Connecting consumer %d\n", n));
+
+ ACE_ConsumerQOS_Factory qos;
+ qos.start_disjunction_group ();
+ qos.insert_type (base_type, 0);
+
+ this->consumers_[n]->connect (this->consumer_admin_.in (),
+ qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ break;
+
+ case 8:
+ {
+ int n = ACE_OS::rand () % this->nsuppliers_;
+
+ // ACE_DEBUG ((LM_DEBUG, "Disconnecting supplier %d\n", n));
+
+ this->suppliers_[n]->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ break;
+
+ case 9:
+ {
+ int n = ACE_OS::rand () % this->nconsumers_;
+
+ // ACE_DEBUG ((LM_DEBUG, "Disconnecting consumer %d\n", n));
+
+ this->consumers_[n]->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ break;
+ }
+}
+
+void
+RND_Driver::event (const RtecEventComm::Event &e
+ ACE_ENV_ARG_DECL)
+{
+ this->timer (e ACE_ENV_ARG_PARAMETER);
+}
+
+// ****************************************************************
+
+void
+RND_Timer::push (const RtecEventComm::EventSet &event
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ ACE_TRY
+ {
+ this->driver_->timer (event[0] ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ }
+ ACE_ENDTRY;
+}
+
+// ****************************************************************
+
+void
+RND_Consumer::connect (RtecEventChannelAdmin::ConsumerAdmin_ptr admin,
+ const RtecEventChannelAdmin::ConsumerQOS &qos
+ ACE_ENV_ARG_DECL)
+{
+ RtecEventChannelAdmin::ProxyPushSupplier_var proxy;
+ {
+ ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock_);
+
+ if (CORBA::is_nil (this->proxy_.in ()))
+ {
+ this->proxy_ = admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ proxy =
+ RtecEventChannelAdmin::ProxyPushSupplier::_duplicate(this->proxy_.in ());
+ }
+ RtecEventComm::PushConsumer_var me =
+ this->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ proxy->connect_push_consumer (me.in (),
+ qos
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+RND_Consumer::disconnect (ACE_ENV_SINGLE_ARG_DECL)
+{
+ ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock_);
+
+ if (CORBA::is_nil (this->proxy_.in ()))
+ return;
+ this->proxy_->disconnect_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ this->proxy_ =
+ RtecEventChannelAdmin::ProxyPushSupplier::_nil ();
+}
+
+void
+RND_Consumer::push (const RtecEventComm::EventSet &event
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ this->driver_->event (event[0] ACE_ENV_ARG_PARAMETER);
+}
+
+void
+RND_Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+}
+
+// ****************************************************************
+
+void
+RND_Supplier::connect (RtecEventChannelAdmin::SupplierAdmin_ptr admin,
+ const RtecEventChannelAdmin::SupplierQOS &qos
+ ACE_ENV_ARG_DECL)
+{
+ RtecEventChannelAdmin::ProxyPushConsumer_var proxy;
+ {
+ ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock_);
+
+ if (CORBA::is_nil (this->proxy_.in ()))
+ {
+ this->proxy_ = admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ proxy =
+ RtecEventChannelAdmin::ProxyPushConsumer::_duplicate(this->proxy_.in ());
+ }
+ RtecEventComm::PushSupplier_var me =
+ this->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ proxy->connect_push_supplier (me.in (),
+ qos
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+RND_Supplier::disconnect (ACE_ENV_SINGLE_ARG_DECL)
+{
+ ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock_);
+
+ if (CORBA::is_nil (this->proxy_.in ()))
+ return;
+ this->proxy_->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ this->proxy_ =
+ RtecEventChannelAdmin::ProxyPushConsumer::_nil ();
+}
+
+void
+RND_Supplier::push_new_event (ACE_ENV_SINGLE_ARG_DECL)
+{
+ RtecEventComm::EventSet event (1);
+ event.length (1);
+ event[0].header.type = base_type;
+ event[0].header.source = 0;
+
+ this->push (event ACE_ENV_ARG_PARAMETER);
+}
+
+void
+RND_Supplier::push (RtecEventComm::EventSet &event
+ ACE_ENV_ARG_DECL)
+{
+ RtecEventChannelAdmin::ProxyPushConsumer_var proxy;
+ {
+ ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock_);
+
+ if (CORBA::is_nil (this->proxy_.in ()))
+ return;
+
+ proxy =
+ RtecEventChannelAdmin::ProxyPushConsumer::_duplicate(this->proxy_.in ());
+ }
+
+ proxy->push (event ACE_ENV_ARG_PARAMETER);
+}
+
+void
+RND_Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+}
+
+int
+RND_Supplier::svc (void)
+{
+ ACE_DEBUG ((LM_DEBUG, "Thread %t started\n"));
+ int percent = 10;
+ int niterations = 5000;
+ for (int i = 0; i != niterations; ++i)
+ {
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ ACE_Time_Value tv (0, 10000);
+ ACE_OS::sleep (tv);
+
+ this->push_new_event (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ }
+ ACE_ENDTRY;
+ if (this->verbose_
+ && i * 100 / niterations >= percent)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Thread %t %d%%\n", percent));
+ percent += 10;
+ }
+ }
+ ACE_DEBUG ((LM_DEBUG, "Thread %t completed\n"));
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/Random.h b/TAO/orbsvcs/tests/Event/Basic/Random.h
new file mode 100644
index 00000000000..a1821d24c0b
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Random.h
@@ -0,0 +1,183 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file Random.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan (coryan@cs.wustl.edu)
+ */
+//=============================================================================
+
+
+#ifndef EC_RANDOM_H
+#define EC_RANDOM_H
+
+#include "orbsvcs/RtecEventCommS.h"
+#include "orbsvcs/RtecEventChannelAdminS.h"
+#include "ace/Task.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class RND_Driver;
+
+class RND_Consumer
+ : public POA_RtecEventComm::PushConsumer
+{
+ // = TITLE
+ // Simple consumer object
+ //
+ // = DESCRIPTION
+ //
+public:
+ /// Constructor
+ RND_Consumer (RND_Driver *driver);
+
+ void push (const RtecEventComm::EventSet &event
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ void connect (RtecEventChannelAdmin::ConsumerAdmin_ptr admin,
+ const RtecEventChannelAdmin::ConsumerQOS &qos
+ ACE_ENV_ARG_DECL);
+ void disconnect (ACE_ENV_SINGLE_ARG_DECL);
+
+protected:
+ /// The driver
+ RND_Driver *driver_;
+
+ /// The supplier.
+ RtecEventChannelAdmin::ProxyPushSupplier_var proxy_;
+
+ /// Synch
+ TAO_SYNCH_MUTEX lock_;
+};
+
+inline
+RND_Consumer::RND_Consumer (RND_Driver *driver)
+ : driver_ (driver)
+{
+}
+
+// ****************************************************************
+
+class RND_Timer : public RND_Consumer
+{
+public:
+ RND_Timer (RND_Driver *driver);
+
+ void push (const RtecEventComm::EventSet &event
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+};
+
+inline
+RND_Timer::RND_Timer (RND_Driver *driver)
+ : RND_Consumer (driver)
+{
+}
+
+// ****************************************************************
+
+class RND_Supplier
+ : public POA_RtecEventComm::PushSupplier
+ , public ACE_Task_Base
+{
+ // = TITLE
+ // Simple supplier object
+ //
+ // = DESCRIPTION
+ //
+public:
+ /// Constructor
+ RND_Supplier (int verbose);
+
+ void connect (RtecEventChannelAdmin::SupplierAdmin_ptr admin,
+ const RtecEventChannelAdmin::SupplierQOS &qos
+ ACE_ENV_ARG_DECL);
+ void disconnect (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Push a single event...
+ void push_new_event (ACE_ENV_SINGLE_ARG_DECL);
+ void push (RtecEventComm::EventSet &event
+ ACE_ENV_ARG_DECL);
+
+ virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// Active method
+ virtual int svc (void);
+
+private:
+ /// The supplier.
+ RtecEventChannelAdmin::ProxyPushConsumer_var proxy_;
+
+ /// Synch
+ TAO_SYNCH_MUTEX lock_;
+
+ /// Be verbose about the progress of the test
+ int verbose_;
+};
+
+inline
+RND_Supplier::RND_Supplier (int verbose)
+ : verbose_ (verbose)
+{
+}
+
+// ****************************************************************
+
+class RND_Driver
+{
+public:
+ RND_Driver (void);
+
+ /// Run the test
+ int run (int argc, char *argv[]);
+
+ /// The main timer has expired
+ void timer (const RtecEventComm::Event &e
+ ACE_ENV_ARG_DECL);
+
+ /// One of the consumers has received an event
+ void event (const RtecEventComm::Event &e
+ ACE_ENV_ARG_DECL);
+
+private:
+ RND_Driver (const RND_Driver &);
+ RND_Driver& operator= (const RND_Driver &);
+
+private:
+ /// The main timer
+ RND_Timer timer_;
+
+ /// The supplier
+ RND_Supplier supplier_;
+
+ /// Number of suppliers
+ int nsuppliers_;
+
+ /// The suppliers
+ RND_Supplier **suppliers_;
+
+ /// Number of consumers
+ int nconsumers_;
+
+ /// The consumers
+ RND_Consumer **consumers_;
+
+ /// Maximum recursion
+ int max_recursion_;
+
+ /// Be verbose about the progress of the test
+ int verbose_;
+
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin_;
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin_;
+};
+
+#endif /* EC_RANDOM_H */
diff --git a/TAO/orbsvcs/tests/Event/Basic/Reconnect.cpp b/TAO/orbsvcs/tests/Event/Basic/Reconnect.cpp
new file mode 100644
index 00000000000..1fd8c294029
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Reconnect.cpp
@@ -0,0 +1,242 @@
+// $Id$
+
+#include "Reconnect.h"
+#include "Consumer.h"
+#include "Supplier.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "ace/Get_Opt.h"
+#include "ace/High_Res_Timer.h"
+
+ACE_RCSID (EC_Tests_Basic,
+ Reconnect,
+ "$Id$")
+
+int
+main (int argc, char *argv [])
+{
+ EC_Reconnect driver;
+ return driver.run (argc, argv);
+}
+
+// ****************************************************************
+
+EC_Reconnect::EC_Reconnect (void)
+ : allow_consumer_reconnect_ (0),
+ allow_supplier_reconnect_ (0),
+ disconnections_ (1000)
+{
+}
+
+int
+EC_Reconnect::parse_args (int& argc, char* argv[])
+{
+ if (this->EC_Driver::parse_args (argc, argv) != 0)
+ return -1;
+
+ ACE_Get_Opt get_opt (argc, argv, "scd:");
+ int opt;
+
+ while ((opt = get_opt ()) != EOF)
+ {
+ switch (opt)
+ {
+ case 'c':
+ this->allow_consumer_reconnect_ = 1;
+ break;
+ case 's':
+ this->allow_supplier_reconnect_ = 1;
+ break;
+ case 'd':
+ this->disconnections_ = ACE_OS::atoi (get_opt.opt_arg ());
+ break;
+
+ case '?':
+ default:
+ this->print_usage ();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+void
+EC_Reconnect::print_args (void) const
+{
+ this->EC_Driver::print_args ();
+
+ ACE_DEBUG ((LM_DEBUG, "EC_Reconnect: \n"
+ " consumer_reconnect = %d\n"
+ " supplier_reconnect = %d\n"
+ " disconnect_count = %d\n",
+ this->allow_consumer_reconnect_,
+ this->allow_supplier_reconnect_,
+ this->disconnections_));
+}
+
+void
+EC_Reconnect::print_usage (void)
+{
+ this->EC_Driver::print_usage ();
+
+ ACE_DEBUG ((LM_DEBUG, "EC_Reconnect usage: [-s] [-c] [-d disc]\n"));
+}
+
+void
+EC_Reconnect::modify_attributes (TAO_EC_Event_Channel_Attributes& attr)
+{
+ attr.consumer_reconnect = this->allow_consumer_reconnect_;
+ attr.supplier_reconnect = this->allow_supplier_reconnect_;
+}
+
+void
+EC_Reconnect::execute_test (ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->execute_consumer_test (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ this->execute_supplier_test (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ ACE_UINT32 gsf = ACE_High_Res_Timer::global_scale_factor ();
+ this->consumer_reconnect_.dump_results ("Reconnect/consumer", gsf);
+ this->supplier_reconnect_.dump_results ("Reconnect/supplier", gsf);
+
+ // this->EC_Driver::execute_test (ACE_ENV_SINGLE_ARG_PARAMETER);
+}
+
+void
+EC_Reconnect::dump_results (void)
+{
+}
+
+void
+EC_Reconnect::execute_consumer_test (ACE_ENV_SINGLE_ARG_DECL)
+{
+ RtecEventChannelAdmin::ConsumerQOS qos;
+ int shutdown_event_type;
+ this->build_consumer_qos (0, qos, shutdown_event_type ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->allow_consumer_reconnect_)
+ {
+ ACE_hrtime_t start_time = ACE_OS::gethrtime ();
+ for (int i = 0; i < this->disconnections_; ++i)
+ {
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+ this->consumers_[0]->connect (qos,
+ shutdown_event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ ACE_hrtime_t stop = ACE_OS::gethrtime ();
+ this->consumer_reconnect_.sample (stop - start_time,
+ stop - start);
+ }
+ }
+ else
+ {
+ ACE_TRY
+ {
+ this->consumers_[0]->connect (qos,
+ shutdown_event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_ERROR, "Expected exception\n"));
+ }
+ ACE_CATCH (RtecEventChannelAdmin::AlreadyConnected, ex)
+ {
+ /* do nothing */
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Expected AlreadyConnected exception");
+ }
+ ACE_ENDTRY;
+
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ this->event_channel_->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ ACE_hrtime_t start_time = ACE_OS::gethrtime ();
+ for (int i = 0; i < this->disconnections_; ++i)
+ {
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+ this->consumers_[0]->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ this->consumers_[0]->connect (consumer_admin.in (),
+ qos,
+ shutdown_event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ ACE_hrtime_t stop = ACE_OS::gethrtime ();
+ this->consumer_reconnect_.sample (stop - start_time,
+ stop - start);
+ }
+ }
+}
+
+void
+EC_Reconnect::execute_supplier_test (ACE_ENV_SINGLE_ARG_DECL)
+{
+ RtecEventChannelAdmin::SupplierQOS qos;
+ int shutdown_event_type;
+ this->build_supplier_qos (0, qos, shutdown_event_type ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->allow_supplier_reconnect_)
+ {
+ ACE_hrtime_t start_time = ACE_OS::gethrtime ();
+ for (int i = 0; i < this->disconnections_; ++i)
+ {
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+ this->suppliers_[0]->connect (qos, shutdown_event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ ACE_hrtime_t stop = ACE_OS::gethrtime ();
+ this->supplier_reconnect_.sample (stop - start_time,
+ stop - start);
+ }
+ }
+ else
+ {
+ ACE_TRY
+ {
+ this->suppliers_[0]->connect (qos, shutdown_event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_ERROR, "Expected exception\n"));
+ }
+ ACE_CATCH (RtecEventChannelAdmin::AlreadyConnected, ex)
+ {
+ /* do nothing */
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Expected AlreadyConnected exception");
+ }
+ ACE_ENDTRY;
+
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ this->event_channel_->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ ACE_hrtime_t start_time = ACE_OS::gethrtime ();
+ for (int i = 0; i < this->disconnections_; ++i)
+ {
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+ this->suppliers_[0]->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ this->suppliers_[0]->connect (supplier_admin.in (),
+ qos,
+ shutdown_event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ ACE_hrtime_t stop = ACE_OS::gethrtime ();
+ this->supplier_reconnect_.sample (stop - start_time,
+ stop - start);
+ }
+ }
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/Reconnect.h b/TAO/orbsvcs/tests/Event/Basic/Reconnect.h
new file mode 100644
index 00000000000..e99cd4b9ffb
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Reconnect.h
@@ -0,0 +1,75 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file Reconnect.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan (coryan@cs.wustl.edu)
+ */
+//=============================================================================
+
+
+#ifndef EC_RECONNECT_H
+#define EC_RECONNECT_H
+
+#include "Driver.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class EC_Reconnect
+ *
+ * @brief Test the EC reconnection feature
+ *
+ * The EC can be configured to allow re-connection of suppliers
+ * and consumers, this test verifies that:
+ * + The EC does *not* allow reconnections if the feature is
+ * disabled (the default)
+ * + The EC does allow reconnections if the feature is enabled
+ * and:
+ * - There are no memory leaks
+ * - Compares the time required for a reconnection vs a complete
+ * connect/disconnect cycle, specially as the number of
+ * suppliers and consumers increases.
+ */
+class EC_Reconnect : public EC_Driver
+{
+public:
+ /// Constructor
+ EC_Reconnect (void);
+
+ // = The EC_Driver methods
+ /// add some command line args to enable/disable reconnections
+ virtual int parse_args (int& argc, char* argv[]);
+ virtual void print_args (void) const;
+ virtual void print_usage (void);
+
+ /// set the reconnection flags
+ virtual void modify_attributes (TAO_EC_Event_Channel_Attributes& attr);
+
+ /// Don't run the suppliers, just test connect and disconnect calls.
+ void execute_test (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Don't dump the EC_Driver results, they are meaningless.
+ void dump_results (void);
+
+ /// Separate the suppliers and consumers.
+ void execute_consumer_test (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS);
+ void execute_supplier_test (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS);
+
+private:
+ /// What aspect of reconnection are we going to test?
+ int allow_consumer_reconnect_;
+ int allow_supplier_reconnect_;
+
+ /// The number of disconnections
+ int disconnections_;
+
+ ACE_Throughput_Stats consumer_reconnect_;
+ ACE_Throughput_Stats supplier_reconnect_;
+};
+
+#endif /* EC_RECONNECT_H */
diff --git a/TAO/orbsvcs/tests/Event/Basic/Schedule.cpp b/TAO/orbsvcs/tests/Event/Basic/Schedule.cpp
new file mode 100644
index 00000000000..b06b6e50355
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Schedule.cpp
@@ -0,0 +1,215 @@
+// $Id$
+
+#include "Schedule.h"
+#include "Consumer.h"
+#include "Supplier.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Sched/Config_Scheduler.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Scheduler_Factory.h"
+#include "orbsvcs/Time_Utilities.h"
+#include "ace/Get_Opt.h"
+#include "ace/Sched_Params.h"
+
+ACE_RCSID(EC_Tests_Basic, Schedule, "$Id$")
+
+int
+main (int argc, char *argv [])
+{
+ EC_Schedule driver;
+ return driver.run (argc, argv);
+}
+
+// ****************************************************************
+
+EC_Schedule::EC_Schedule (void)
+ : scheduler_impl_ (0)
+{
+}
+
+int
+EC_Schedule::parse_args (int& argc, char* argv[])
+{
+ if (this->EC_Driver::parse_args (argc, argv) != 0)
+ return -1;
+
+ return 0;
+}
+
+void
+EC_Schedule::print_args (void) const
+{
+ this->EC_Driver::print_args ();
+}
+
+void
+EC_Schedule::print_usage (void)
+{
+ this->EC_Driver::print_usage ();
+}
+
+void
+EC_Schedule::initialize_ec_impl (ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->scheduler_impl_ = new ACE_Config_Scheduler;
+ this->scheduler_ = this->scheduler_impl_->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->EC_Driver::initialize_ec_impl (ACE_ENV_SINGLE_ARG_PARAMETER);
+}
+
+void
+EC_Schedule::modify_attributes (TAO_EC_Event_Channel_Attributes& attr)
+{
+ attr.scheduler = this->scheduler_.in (); // no need to dup
+}
+
+void
+EC_Schedule::cleanup_ec (void)
+{
+ this->EC_Driver::cleanup_ec ();
+ delete this->scheduler_impl_;
+}
+
+void
+EC_Schedule::execute_test (ACE_ENV_SINGLE_ARG_DECL)
+{
+ CORBA::Long min_priority =
+ (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO)
+ + ACE_Sched_Params::priority_max (ACE_SCHED_FIFO)) / 2;
+ CORBA::Long max_priority =
+ ACE_Sched_Params::priority_max (ACE_SCHED_FIFO);
+
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG,
+ "EC_Schedule (%P|%t) computing schedule\n"));
+
+ RtecScheduler::RT_Info_Set_var infos;
+ RtecScheduler::Dependency_Set_var deps;
+ RtecScheduler::Config_Info_Set_var configs;
+ RtecScheduler::Scheduling_Anomaly_Set_var anomalies;
+ this->scheduler_->compute_scheduling (min_priority, max_priority,
+ infos.out (),
+ deps.out (),
+ configs.out (),
+ anomalies.out ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG,
+ "EC_Schedule (%P|%t) schedule prepared\n"));
+
+ ACE_Scheduler_Factory::dump_schedule (infos.in (),
+ deps.in (),
+ configs.in (),
+ anomalies.in ());
+
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG,
+ "EC_Schedule (%P|%t) schedule dumped\n"));
+
+}
+
+void
+EC_Schedule::build_consumer_qos (
+ int i,
+ RtecEventChannelAdmin::ConsumerQOS& qos,
+ int& shutdown_event_type
+ ACE_ENV_ARG_DECL)
+{
+ char name[128];
+ ACE_OS::sprintf (name, "EC_Schedule::Consumer::%04x", i);
+
+ RtecScheduler::handle_t rt_info =
+ this->scheduler_->create (name ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // The worst case execution time is far less than 2
+ // milliseconds, but that is a safe estimate....
+ ACE_Time_Value tv (0, 2000);
+ TimeBase::TimeT time;
+ ORBSVCS_Time::Time_Value_to_TimeT (time, tv);
+ this->scheduler_->set (rt_info,
+ RtecScheduler::VERY_HIGH_CRITICALITY,
+ time, time, time,
+ 0,
+ RtecScheduler::VERY_LOW_IMPORTANCE,
+ time,
+ 0,
+ RtecScheduler::OPERATION
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ int type_start =
+ this->consumer_type_start_
+ + i * this->consumer_type_shift_;
+
+ shutdown_event_type = type_start + this->consumer_type_count_;
+
+ ACE_ConsumerQOS_Factory qos_factory;
+ qos_factory.start_disjunction_group ();
+ qos_factory.insert_type (shutdown_event_type, rt_info);
+
+ for (int j = 0; j != this->consumer_type_count_; ++j)
+ qos_factory.insert_type (type_start + j, rt_info);
+
+ qos = qos_factory.get_ConsumerQOS ();
+}
+
+void
+EC_Schedule::build_supplier_qos (
+ int i,
+ RtecEventChannelAdmin::SupplierQOS& qos,
+ int& shutdown_event_type
+ ACE_ENV_ARG_DECL)
+{
+ char name[128];
+ ACE_OS::sprintf (name, "EC_Schedule::Supplier::%04x", i);
+
+ RtecScheduler::handle_t rt_info =
+ this->scheduler_->create (name ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ ACE_Time_Value tv (0, this->burst_pause_);
+ RtecScheduler::Period_t rate = tv.usec () * 10;
+
+ // 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);
+ TimeBase::TimeT time;
+ ORBSVCS_Time::Time_Value_to_TimeT (time, tv);
+ this->scheduler_->set (rt_info,
+ RtecScheduler::VERY_HIGH_CRITICALITY,
+ time, time, time,
+ rate,
+ RtecScheduler::VERY_LOW_IMPORTANCE,
+ time,
+ 1,
+ RtecScheduler::OPERATION
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ int type_start = this->supplier_type_start_ + i*this->supplier_type_shift_;
+ int supplier_id = i + 1;
+ shutdown_event_type = type_start + this->supplier_type_count_;
+
+ ACE_SupplierQOS_Factory qos_factory;
+ for (int j = 0; j != this->supplier_type_count_; ++j)
+ qos_factory.insert (supplier_id,
+ type_start + j,
+ rt_info, 1);
+
+ qos_factory.insert (supplier_id,
+ shutdown_event_type,
+ rt_info, 1);
+
+ qos = qos_factory.get_SupplierQOS ();
+}
+
+void
+EC_Schedule::dump_results (void)
+{
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/Schedule.h b/TAO/orbsvcs/tests/Event/Basic/Schedule.h
new file mode 100644
index 00000000000..c139b699227
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Schedule.h
@@ -0,0 +1,85 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file Schedule.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan (coryan@cs.wustl.edu)
+ */
+//=============================================================================
+
+
+#ifndef EC_SCHEDULE_H
+#define EC_SCHEDULE_H
+
+#include "Driver.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "orbsvcs/RtecSchedulerS.h"
+
+/**
+ * @class EC_Schedule
+ *
+ * @brief Test the EC scheduling test
+ *
+ * The EC can be used in conjunction with the scheduling service
+ * to analyze the schedulabity of a system and compute priority
+ * assignments that guarantee the correct behavior of it.
+ * Most of the work is actually done by the scheduler (as it
+ * should be), the event channel simply plays two roles:
+ * 1) Feed the scheduler with the dependency information between
+ * consumers and suppliers based on their QoS requirements,
+ * subscriptions and publications.
+ * 2) At run-time use the scheduler information to dispatch the
+ * events at the right priority.
+ * The current version only verifies the first role.
+ */
+class EC_Schedule : public EC_Driver
+{
+public:
+ /// Constructor
+ EC_Schedule (void);
+
+ // = The EC_Driver methods
+ /// add some command line args to change the scheduling service to
+ /// use.
+ virtual int parse_args (int& argc, char* argv[]);
+ virtual void print_args (void) const;
+ virtual void print_usage (void);
+
+ /// Set the scheduling service attribute
+ void initialize_ec_impl (ACE_ENV_SINGLE_ARG_DECL);
+ void cleanup_ec (void);
+ virtual void modify_attributes (TAO_EC_Event_Channel_Attributes& attr);
+
+ /// Don't run the suppliers, just compute the schedule.
+ void execute_test (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Don't dump the EC_Driver results, they are meaningless.
+ void dump_results (void);
+
+ /// This time really connect to the scheduler
+ virtual void build_consumer_qos (
+ int i,
+ RtecEventChannelAdmin::ConsumerQOS& qos,
+ int& shutdown_event_type
+ ACE_ENV_ARG_DECL_NOT_USED);
+ virtual void build_supplier_qos (
+ int i,
+ RtecEventChannelAdmin::SupplierQOS& qos,
+ int& shutdown_event_type
+ ACE_ENV_ARG_DECL_NOT_USED);
+
+private:
+ /// The scheduler implementation
+ POA_RtecScheduler::Scheduler *scheduler_impl_;
+
+ /// The scheduler object reference
+ RtecScheduler::Scheduler_var scheduler_;
+};
+
+#endif /* EC_SCHEDULE_H */
diff --git a/TAO/orbsvcs/tests/Event/Basic/Shutdown.cpp b/TAO/orbsvcs/tests/Event/Basic/Shutdown.cpp
new file mode 100644
index 00000000000..ea2c18a1743
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Shutdown.cpp
@@ -0,0 +1,89 @@
+// $Id$
+
+#include "Shutdown.h"
+#include "Consumer.h"
+#include "Supplier.h"
+
+ACE_RCSID(EC_Tests_Basic, Shutdown, "$Id$")
+
+int
+main (int argc, char *argv [])
+{
+ EC_Shutdown driver;
+ return driver.run (argc, argv);
+}
+
+// ****************************************************************
+
+EC_Shutdown::EC_Shutdown (void)
+ : consumer_disconnects_ (0),
+ supplier_disconnects_ (0)
+{
+}
+
+void
+EC_Shutdown::execute_test (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Shutdown (%P|%t) destroying EC\n"));
+
+ this->destroy_ec (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Shutdown (%P|%t) ec destroyed\n"));
+
+ this->deactivate_ec (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Shutdown (%P|%t) ec deactivated\n"));
+
+ this->cleanup_ec ();
+
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Shutdown (%P|%t) ec cleanup\n"));
+
+ this->initialize_ec_impl (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ this->connect_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ this->connect_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Shutdown (%P|%t) status reset\n"));
+
+ // this->EC_Driver::execute_test (ACE_ENV_SINGLE_ARG_PARAMETER);
+}
+
+void
+EC_Shutdown::dump_results (void)
+{
+ if (this->consumer_disconnects_ != this->n_consumers_)
+ ACE_ERROR ((LM_ERROR,
+ "Unexpected number (%d) of consumers disconnected\n",
+ this->consumer_disconnects_));
+
+ if (this->supplier_disconnects_ != this->n_suppliers_)
+ ACE_ERROR ((LM_ERROR,
+ "Unexpected number (%d) of suppliers disconnected\n",
+ this->supplier_disconnects_));
+}
+
+void
+EC_Shutdown::consumer_disconnect (void* cookie
+ ACE_ENV_ARG_DECL_NOT_USED)
+{
+ this->consumer_disconnects_++;
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "Consumer %x has been disconnected\n", cookie));
+}
+
+void
+EC_Shutdown::supplier_disconnect (void* cookie
+ ACE_ENV_ARG_DECL_NOT_USED)
+{
+ this->supplier_disconnects_++;
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "Supplier %x has been disconnected\n", cookie));
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/Shutdown.h b/TAO/orbsvcs/tests/Event/Basic/Shutdown.h
new file mode 100644
index 00000000000..81050629f9f
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Shutdown.h
@@ -0,0 +1,59 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file Shutdown.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan (coryan@cs.wustl.edu)
+ */
+//=============================================================================
+
+
+#ifndef EC_SHUTDOWN_H
+#define EC_SHUTDOWN_H
+
+#include "Driver.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class EC_Shutdown
+ *
+ * @brief Test the EC shutdown features
+ *
+ * The EC must inform its suppliers and consumers on the event of
+ * its destruction.
+ * This test exercises that feature of the EC.
+ */
+class EC_Shutdown : public EC_Driver
+{
+public:
+ /// Constructor
+ EC_Shutdown (void);
+
+ // = The EC_Driver methods
+ /// Don't run the suppliers just create the EC and then destroy it.
+ void execute_test (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Don't dump the EC_Driver results, they are meaningless.
+ void dump_results (void);
+
+ /// One of the consumers in the test has been disconnected from the EC
+ virtual void consumer_disconnect (void* consumer_cookie
+ ACE_ENV_ARG_DECL);
+
+ /// One of the suppliers in the test has been disconnected from the EC
+ virtual void supplier_disconnect (void* supplier_cookie
+ ACE_ENV_ARG_DECL);
+
+
+private:
+ /// Number of consumer and supplier disconnect messages.
+ int consumer_disconnects_;
+ int supplier_disconnects_;
+};
+
+#endif /* EC_SHUTDOWN_H */
diff --git a/TAO/orbsvcs/tests/Event/Basic/Timeout.cpp b/TAO/orbsvcs/tests/Event/Basic/Timeout.cpp
new file mode 100644
index 00000000000..f00ec8abab4
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Timeout.cpp
@@ -0,0 +1,205 @@
+// $Id$
+
+#include "Counting_Consumer.h"
+#include "Counting_Supplier.h"
+
+#include "orbsvcs/Time_Utilities.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+
+ACE_RCSID (EC_Tests,
+ Timeout,
+ "$Id$")
+
+// ****************************************************************
+
+int
+main (int argc, char* argv[])
+{
+ TAO_EC_Default_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;
+
+ 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;
+
+ // ****************************************************************
+
+ TAO_EC_Event_Channel_Attributes attributes (poa.in (),
+ poa.in ());
+
+ TAO_EC_Event_Channel ec_impl (attributes);
+ ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::EventChannel_var event_channel =
+ ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+
+ // ****************************************************************
+
+ // Obtain the consumer admin..
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain the supplier admin..
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Supplier supplier;
+
+ supplier.activate (consumer_admin.in (),
+ 50 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier.connect (supplier_admin.in (),
+ 0, 20,
+ 0, 20
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Consumer interval_consumer ("Consumer/interval");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+
+ {
+ // Let's say that the execution time for event 2 is 1
+ // milliseconds...
+ ACE_Time_Value tv (0, 100000);
+ TimeBase::TimeT time;
+ ORBSVCS_Time::Time_Value_to_TimeT (time, tv);
+
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group ();
+ // The types int the range [0,ACE_ES_EVENT_UNDEFINED) are
+ // reserved for the EC...
+ consumer_qos.insert_time (ACE_ES_EVENT_INTERVAL_TIMEOUT,
+ time,
+ 0);
+
+ interval_consumer.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ EC_Counting_Consumer conjunction_consumer ("Consumer/conjunction");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+ {
+ // Let's say that the execution time for event 2 is 1
+ // milliseconds...
+ ACE_Time_Value tv (0, 200000);
+ TimeBase::TimeT time;
+ ORBSVCS_Time::Time_Value_to_TimeT (time, tv);
+
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_conjunction_group ();
+ consumer_qos.insert_time (ACE_ES_EVENT_INTERVAL_TIMEOUT,
+ time,
+ 0);
+ consumer_qos.insert_type (20,
+ 0);
+
+ conjunction_consumer.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ EC_Counting_Consumer deadline_consumer ("Consumer/deadline");
+
+ {
+ ACE_Time_Value tv (0, 80000);
+ TimeBase::TimeT time;
+ ORBSVCS_Time::Time_Value_to_TimeT (time, tv);
+
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group ();
+ consumer_qos.insert_time (ACE_ES_EVENT_DEADLINE_TIMEOUT,
+ time,
+ 0);
+ consumer_qos.insert_type (20,
+ 0);
+
+ deadline_consumer.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ ACE_Time_Value tv (5, 0);
+ // Wait for events, using work_pending()/perform_work() may help
+ // or using another thread, this example is too simple for that.
+ orb->run (tv);
+
+ // ****************************************************************
+
+ deadline_consumer.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ conjunction_consumer.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ interval_consumer.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ supplier.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ interval_consumer.dump_results (50, 5);
+ conjunction_consumer.dump_results (25, 5);
+ deadline_consumer.dump_results (100, 5);
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service");
+ return 1;
+ }
+ ACE_ENDTRY;
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/Wildcard.cpp b/TAO/orbsvcs/tests/Event/Basic/Wildcard.cpp
new file mode 100644
index 00000000000..af77cc9fcbd
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/Wildcard.cpp
@@ -0,0 +1,319 @@
+// $Id$
+
+#include "Counting_Consumer.h"
+#include "Counting_Supplier.h"
+#include "orbsvcs/Time_Utilities.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+
+ACE_RCSID (EC_Tests,
+ Wildcard,
+ "$Id$")
+
+int
+main (int argc, char* argv[])
+{
+ TAO_EC_Default_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;
+
+ 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;
+
+ // ****************************************************************
+
+ TAO_EC_Event_Channel_Attributes attributes (poa.in (),
+ poa.in ());
+
+ TAO_EC_Event_Channel ec_impl (attributes);
+ ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::EventChannel_var event_channel =
+ ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+
+ // ****************************************************************
+
+ // Obtain the consumer admin..
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain the supplier admin..
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ const int event_type = 20;
+ const int event_source = 10;
+ const int milliseconds = 50;
+
+ EC_Counting_Supplier supplier;
+
+ supplier.activate (consumer_admin.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier.connect (supplier_admin.in (),
+ event_source,
+ event_type,
+ event_source,
+ event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Supplier other_supplier;
+
+ other_supplier.activate (consumer_admin.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ other_supplier.connect (supplier_admin.in (),
+ event_source + 1,
+ event_type + 1,
+ event_source + 1,
+ event_type + 1
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Supplier any_source_supplier;
+
+ any_source_supplier.activate (consumer_admin.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ any_source_supplier.connect (supplier_admin.in (),
+ 0,
+ event_type,
+ event_source,
+ event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Supplier any_type_supplier;
+
+ any_type_supplier.activate (consumer_admin.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ any_type_supplier.connect (supplier_admin.in (),
+ event_source,
+ 0,
+ event_source,
+ event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Supplier wildcard_supplier;
+
+ wildcard_supplier.activate (consumer_admin.in (),
+ milliseconds
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ wildcard_supplier.connect (supplier_admin.in (),
+ 0,
+ 0,
+ event_source,
+ event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ EC_Counting_Consumer regular_consumer ("Consumer/regular");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group ();
+ consumer_qos.insert (event_source, event_type, 0);
+
+ regular_consumer.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ EC_Counting_Consumer any_type_consumer ("Consumer/any_type");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group ();
+ consumer_qos.insert (event_source, 0, 0);
+
+ any_type_consumer.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ EC_Counting_Consumer any_source_consumer ("Consumer/any_source");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group ();
+ consumer_qos.insert (0, event_type, 0);
+
+ any_source_consumer.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ EC_Counting_Consumer wildcard_consumer ("Consumer/wildcard");
+ // Create a consumer, intialize its RT_Info structures, and
+ // connnect to the event channel....
+
+
+ {
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group ();
+ consumer_qos.insert (0, 0, 0);
+
+ wildcard_consumer.connect (consumer_admin.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // ****************************************************************
+
+ ACE_Time_Value tv (5, 0);
+ // Wait for events, using work_pending()/perform_work() may help
+ // or using another thread, this example is too simple for that.
+ orb->run (tv);
+
+ // ****************************************************************
+
+ wildcard_consumer.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ any_source_consumer.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ any_type_consumer.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ regular_consumer.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ wildcard_supplier.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ wildcard_supplier.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ any_type_supplier.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ any_source_supplier.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ any_source_supplier.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ other_supplier.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ other_supplier.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ supplier.deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ supplier.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ****************************************************************
+
+ CORBA::ULong expected =
+ wildcard_supplier.event_count
+ + any_type_supplier.event_count
+ + any_source_supplier.event_count
+ + other_supplier.event_count
+ + supplier.event_count;
+ wildcard_consumer.dump_results (expected, 5);
+
+ expected =
+ wildcard_supplier.event_count
+ + any_type_supplier.event_count
+ + any_source_supplier.event_count
+ // NOT THIS ONE + other_supplier.event_count
+ + supplier.event_count;
+ any_source_consumer.dump_results (expected, 5);
+
+ expected =
+ wildcard_supplier.event_count
+ + any_type_supplier.event_count
+ + any_source_supplier.event_count
+ // NOT THIS ONE + other_supplier.event_count
+ + supplier.event_count;
+ any_type_consumer.dump_results (expected, 5);
+
+ expected =
+ wildcard_supplier.event_count
+ + any_type_supplier.event_count
+ + any_source_supplier.event_count
+ // NOT THIS ONE + other_supplier.event_count
+ + supplier.event_count;
+ regular_consumer.dump_results (expected, 5);
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service");
+ return 1;
+ }
+ ACE_ENDTRY;
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/control.conf b/TAO/orbsvcs/tests/Event/Basic/control.conf
new file mode 100644
index 00000000000..bfedbdcfa71
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/control.conf
@@ -0,0 +1,2 @@
+# $Id$
+static EC_Factory "-ECConsumerControl reactive -ECSupplierControl reactive -ECConsumerControlPeriod 50000 -ECSupplierControlPeriod 50000"
diff --git a/TAO/orbsvcs/tests/Event/Basic/control.conf.xml b/TAO/orbsvcs/tests/Event/Basic/control.conf.xml
new file mode 100644
index 00000000000..05dd8b01c20
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/control.conf.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0'?>
+<!-- Converted from ./orbsvcs/tests/Event/Basic/control.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- $Id$ -->
+ <static id="EC_Factory" params="-ECConsumerControl reactive -ECSupplierControl reactive -ECConsumerControlPeriod 50000 -ECSupplierControlPeriod 50000"/>
+</ACE_Svc_Conf>
diff --git a/TAO/orbsvcs/tests/Event/Basic/exhaustive_test.pl b/TAO/orbsvcs/tests/Event/Basic/exhaustive_test.pl
new file mode 100755
index 00000000000..74b7987f7d8
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/exhaustive_test.pl
@@ -0,0 +1,60 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+# This is a Perl script that runs the client and all the other servers that
+# are needed
+
+use lib '../../../../../bin';
+use PerlACE::Run_Test;
+
+$status = 0;
+
+$conf_file = PerlACE::LocalFile ("exhaustive$PerlACE::svcconf_ext");
+
+@dispatching_configs = ("-ECDispatching reactive",
+ "-ECDispatching mt -ECDispatchingThreads 4");
+@collection_strategies = ("copy_on_read",
+ "copy_on_write",
+ "delayed");
+@collection_types = ("list",
+ "rb_tree");
+@filtering_configs = ("-ECFiltering prefix -ECSupplierFilter per-supplier",
+ "-ECFiltering prefix -ECSupplierFilter null");
+
+foreach $d (@dispatching_configs) {
+ foreach $f (@filtering_configs) {
+ foreach $c (@collection_strategies) {
+ foreach $t (@collection_types) {
+ my $collection = "mt:".$c.":".$t;
+
+ my $config = 'static EC_Factory "'
+ .$d
+ ." -ECProxyPushConsumerCollection ".$collection
+ ." -ECProxyPushSupplierCollection ".$collection
+ ." ".$f
+ .'"';
+
+ open (CONFIG,">$conf_file") || die "Cannot open $conf_file\n";
+ print CONFIG $config, "\n";
+ close (CONFIG);
+
+ print STDERR "\n\n", $config, "\n";
+
+ system ("purify.exe "
+ . "/run .\\Release\\Random.exe "
+ . " -ORBSvcConf $conf_file"
+ . " -suppliers 16"
+ . " -consumers 16"
+ . " -max_recursion 0");
+ }
+ }
+ }
+}
+
+unlink "$conf_file";
+
+exit $status;
diff --git a/TAO/orbsvcs/tests/Event/Basic/mt.svc.conf b/TAO/orbsvcs/tests/Event/Basic/mt.svc.conf
new file mode 100644
index 00000000000..8ba2c743960
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/mt.svc.conf
@@ -0,0 +1,2 @@
+# $Id$
+static EC_Factory "-ECObserver null -ECProxyPushConsumerCollection mt:delayed:list -ECProxyPushSupplierCollection mt:delayed:list -ECdispatching reactive -ECscheduling null -ECfiltering basic -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"
diff --git a/TAO/orbsvcs/tests/Event/Basic/mt.svc.conf.xml b/TAO/orbsvcs/tests/Event/Basic/mt.svc.conf.xml
new file mode 100644
index 00000000000..9eb9319264f
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/mt.svc.conf.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0'?>
+<!-- Converted from ./orbsvcs/tests/Event/Basic/mt.svc.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- $Id$ -->
+ <static id="EC_Factory" params="-ECObserver null -ECProxyPushConsumerCollection mt:delayed:list -ECProxyPushSupplierCollection mt:delayed:list -ECdispatching reactive -ECscheduling null -ECfiltering basic -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"/>
+</ACE_Svc_Conf>
diff --git a/TAO/orbsvcs/tests/Event/Basic/observer.conf b/TAO/orbsvcs/tests/Event/Basic/observer.conf
new file mode 100644
index 00000000000..c4639fe7f59
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/observer.conf
@@ -0,0 +1,2 @@
+# $Id$
+static EC_Factory "-ECObserver basic -ECProxyPushConsumerCollection mt:delayed:list -ECProxyPushSupplierCollection mt:delayed:list -ECDispatching reactive -ECscheduling null -ECfiltering basic -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"
diff --git a/TAO/orbsvcs/tests/Event/Basic/observer.conf.xml b/TAO/orbsvcs/tests/Event/Basic/observer.conf.xml
new file mode 100644
index 00000000000..3629833dff0
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/observer.conf.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0'?>
+<!-- Converted from ./orbsvcs/tests/Event/Basic/observer.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- $Id$ -->
+ <static id="EC_Factory" params="-ECObserver basic -ECProxyPushConsumerCollection mt:delayed:list -ECProxyPushSupplierCollection mt:delayed:list -ECDispatching reactive -ECscheduling null -ECfiltering basic -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"/>
+</ACE_Svc_Conf>
diff --git a/TAO/orbsvcs/tests/Event/Basic/rteventtestexe.mpb b/TAO/orbsvcs/tests/Event/Basic/rteventtestexe.mpb
new file mode 100644
index 00000000000..63ef09376f3
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/rteventtestexe.mpb
@@ -0,0 +1,13 @@
+// -*- MPC -*-
+// $Id$
+
+project : messaging, rteventexe, rtevent_serv, naming, iortable {
+ after += Event_Test_Lib
+ libs += ECTests
+
+ specific (automake) {
+ includes += $(srcdir)/../lib
+ } else {
+ includes += ../lib
+ }
+}
diff --git a/TAO/orbsvcs/tests/Event/Basic/run_test.pl b/TAO/orbsvcs/tests/Event/Basic/run_test.pl
new file mode 100755
index 00000000000..daa88c808d1
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/run_test.pl
@@ -0,0 +1,101 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+# This is a Perl script that runs the client and all the other servers that
+# are needed
+
+use lib '../../../../../bin';
+use PerlACE::Run_Test;
+
+$status = 0;
+
+$svc_conf = PerlACE::LocalFile ("svc$PerlACE::svcconf_ext");
+$observer_conf = PerlACE::LocalFile ("observer$PerlACE::svcconf_ext");
+$svc_complex_conf = PerlACE::LocalFile ("svc.complex$PerlACE::svcconf_ext");
+$mt_svc_conf = PerlACE::LocalFile ("mt.svc$PerlACE::svcconf_ext");
+$svc_complex_conf = PerlACE::LocalFile ("svc.complex$PerlACE::svcconf_ext");
+$control_conf = PerlACE::LocalFile ("control$PerlACE::svcconf_ext");
+
+sub RunTest ($$$)
+{
+ my $message = shift;
+ my $program = shift;
+ my $arguments = shift;
+
+ my $TEST = new PerlACE::Process ($program, $arguments);
+
+ print STDERR "\n\n$message\n";
+
+ my $test = $TEST->SpawnWaitKill (240);
+
+ if ($test != 0) {
+ print STDERR "ERROR: Test returned $test\n";
+ $status = 1;
+ }
+}
+
+RunTest ("Reconnect suppliers and consumers, using disconnect/connect calls",
+ "Reconnect",
+ "-ORBsvcconf $svc_conf -suppliers 100 -consumers 100 -d 100");
+
+RunTest ("Reconnect suppliers and consumers, using connect calls",
+ "Reconnect",
+ "-ORBsvcconf $svc_conf -suppliers 100 -consumers 100 -d 100 -s -c");
+
+RunTest ("Shutdown EC with clients still attached",
+ "Shutdown",
+ "-ORBsvcconf $svc_conf -suppliers 5 -consumers 5");
+
+RunTest ("Gateway test",
+ "Gateway",
+ "-ORBsvcconf $observer_conf");
+
+RunTest ("Complex event channel test, multiple ECs connected through gateways",
+ "Observer",
+ "-ORBsvcconf $observer_conf -consumer_tshift 0 -consumers 5 -supplier_tshift 0 -suppliers 2 -burstsize 10 -burstcount 10 -burstpause 0");
+
+RunTest ("Timeout tests",
+ "Timeout",
+ "-ORBsvcconf $svc_conf");
+
+RunTest ("Wildcard tests",
+ "Wildcard",
+ "-ORBsvcconf $svc_conf");
+
+RunTest ("Negation tests",
+ "Negation",
+ "-ORBsvcconf $svc_conf");
+
+RunTest ("Bitmask tests",
+ "Bitmask",
+ "-ORBSvcConf $svc_complex_conf");
+
+RunTest ("Disconnect callbacks test",
+ "Disconnect",
+ "-ORBsvcconf $svc_conf");
+
+RunTest ("MT Disconnects test",
+ "MT_Disconnect",
+ "-ORBSvcConf $mt_svc_conf");
+
+RunTest ("Atomic Reconnection test",
+ "Atomic_Reconnect",
+ "-ORBSvcConf $mt_svc_conf");
+
+RunTest ("Complex filter",
+ "Complex",
+ "-ORBSvcConf $svc_complex_conf");
+
+RunTest ("Control test",
+ "Control",
+ "-ORBSvcConf $control_conf");
+
+RunTest ("Random test",
+ "Random",
+ "-ORBSvcConf $svc_conf -suppliers 4 -consumers 4 -max_recursion 1");
+
+exit $status;
diff --git a/TAO/orbsvcs/tests/Event/Basic/sched.conf b/TAO/orbsvcs/tests/Event/Basic/sched.conf
new file mode 100644
index 00000000000..bfc09bc8bdf
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/sched.conf
@@ -0,0 +1,3 @@
+# $Id$
+
+dynamic EC_Factory Service_Object * TAO_RTSchedEvent:_make_TAO_EC_Sched_Factory() "-ECDispatching priority -ECScheduling priority -ECFiltering priority -ECProxyPushConsumerCollection mt:copy_on_write:list -ECProxyPushSupplierCollection mt:copy_on_write:list -ECProxyConsumerLock thread -ECProxySupplierLock thread -ECSupplierFiltering per-supplier"
diff --git a/TAO/orbsvcs/tests/Event/Basic/sched.conf.xml b/TAO/orbsvcs/tests/Event/Basic/sched.conf.xml
new file mode 100644
index 00000000000..d4961bedca2
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/sched.conf.xml
@@ -0,0 +1,8 @@
+<?xml version='1.0'?>
+<!-- Converted from ./orbsvcs/tests/Event/Basic/sched.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- $Id$ -->
+ <dynamic id="EC_Factory" type="Service_Object">
+ <initializer path="TAO_RTSchedEvent" init="_make_TAO_EC_Sched_Factory" params="-ECDispatching priority -ECScheduling priority -ECFiltering priority -ECProxyPushConsumerCollection mt:copy_on_write:list -ECProxyPushSupplierCollection mt:copy_on_write:list -ECProxyConsumerLock thread -ECProxySupplierLock thread -ECSupplierFiltering per-supplier"/>
+ </dynamic>
+</ACE_Svc_Conf>
diff --git a/TAO/orbsvcs/tests/Event/Basic/svc.complex.conf b/TAO/orbsvcs/tests/Event/Basic/svc.complex.conf
new file mode 100644
index 00000000000..0b3e29e08b1
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/svc.complex.conf
@@ -0,0 +1,2 @@
+# $Id$
+static EC_Factory "-ECProxyPushConsumerCollection mt:delayed:list -ECProxyPushSupplierCollection mt:delayed:list -ECdispatching reactive -ECfiltering prefix -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"
diff --git a/TAO/orbsvcs/tests/Event/Basic/svc.complex.conf.xml b/TAO/orbsvcs/tests/Event/Basic/svc.complex.conf.xml
new file mode 100644
index 00000000000..7a4a28be570
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/svc.complex.conf.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0'?>
+<!-- Converted from ./orbsvcs/tests/Event/Basic/svc.complex.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- $Id$ -->
+ <static id="EC_Factory" params="-ECProxyPushConsumerCollection mt:delayed:list -ECProxyPushSupplierCollection mt:delayed:list -ECdispatching reactive -ECfiltering prefix -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"/>
+</ACE_Svc_Conf>
diff --git a/TAO/orbsvcs/tests/Event/Basic/svc.conf b/TAO/orbsvcs/tests/Event/Basic/svc.conf
new file mode 100644
index 00000000000..c4d0cc45fbf
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/svc.conf
@@ -0,0 +1,2 @@
+# $Id$
+static EC_Factory "-ECProxyPushConsumerCollection mt:copy_on_write:list -ECProxyPushSupplierCollection mt:copy_on_write:list -ECdispatching reactive -ECfiltering basic -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"
diff --git a/TAO/orbsvcs/tests/Event/Basic/svc.conf.xml b/TAO/orbsvcs/tests/Event/Basic/svc.conf.xml
new file mode 100644
index 00000000000..491ecb5aeb9
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Basic/svc.conf.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0'?>
+<!-- Converted from ./orbsvcs/tests/Event/Basic/svc.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- $Id$ -->
+ <static id="EC_Factory" params="-ECProxyPushConsumerCollection mt:copy_on_write:list -ECProxyPushSupplierCollection mt:copy_on_write:list -ECdispatching reactive -ECfiltering basic -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"/>
+</ACE_Svc_Conf>
diff --git a/TAO/orbsvcs/tests/Event/Makefile.am b/TAO/orbsvcs/tests/Event/Makefile.am
new file mode 100644
index 00000000000..ad70d16ed4e
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Makefile.am
@@ -0,0 +1,16 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## ../bin/mwc.pl -type automake -noreldefs TAO.mwc
+
+SUBDIRS = \
+ Mcast \
+ lib \
+ Performance \
+ Basic
+
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Common/ECMcastTests_export.h b/TAO/orbsvcs/tests/Event/Mcast/Common/ECMcastTests_export.h
new file mode 100644
index 00000000000..9c398b58046
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Common/ECMcastTests_export.h
@@ -0,0 +1,40 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl
+// ------------------------------
+#ifndef ECMCASTTESTS_EXPORT_H
+#define ECMCASTTESTS_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (TAO_AS_STATIC_LIBS)
+# if !defined (ECMCASTTESTS_HAS_DLL)
+# define ECMCASTTESTS_HAS_DLL 0
+# endif /* ! ECMCASTTESTS_HAS_DLL */
+#else
+# if !defined (ECMCASTTESTS_HAS_DLL)
+# define ECMCASTTESTS_HAS_DLL 1
+# endif /* ! ECMCASTTESTS_HAS_DLL */
+#endif
+
+#if defined (ECMCASTTESTS_HAS_DLL) && (ECMCASTTESTS_HAS_DLL == 1)
+# if defined (ECMCASTTESTS_BUILD_DLL)
+# define ECMcastTests_Export ACE_Proper_Export_Flag
+# define ECMCASTTESTS_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define ECMCASTTESTS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* ECMCASTTESTS_BUILD_DLL */
+# define ECMcastTests_Export ACE_Proper_Import_Flag
+# define ECMCASTTESTS_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define ECMCASTTESTS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* ECMCASTTESTS_BUILD_DLL */
+#else /* ECMCASTTESTS_HAS_DLL == 1 */
+# define ECMcastTests_Export
+# define ECMCASTTESTS_SINGLETON_DECLARATION(T)
+# define ECMCASTTESTS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* ECMCASTTESTS_HAS_DLL == 1 */
+
+#endif /* ECMCASTTESTS_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Common/ECMcastTests_lib.mpc b/TAO/orbsvcs/tests/Event/Mcast/Common/ECMcastTests_lib.mpc
new file mode 100644
index 00000000000..d9c5af671ff
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Common/ECMcastTests_lib.mpc
@@ -0,0 +1,7 @@
+// -*- MPC -*-
+// $Id$
+
+project: rtevent_serv {
+ sharedname = ECMcastTests
+ dynamicflags = ECMCASTTESTS_BUILD_DLL
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Common/EC_Wrapper.cpp b/TAO/orbsvcs/tests/Event/Mcast/Common/EC_Wrapper.cpp
new file mode 100644
index 00000000000..fe118587fac
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Common/EC_Wrapper.cpp
@@ -0,0 +1,163 @@
+// $Id$
+
+#include "EC_Wrapper.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "ace/Auto_Ptr.h"
+
+EC_Wrapper::EC_Wrapper (void)
+ : ec_impl_ (0),
+ orb_ ()
+{
+}
+
+TAO_EC_Servant_Var<EC_Wrapper>
+EC_Wrapper::create (void)
+{
+ TAO_EC_Servant_Var<EC_Wrapper> w;
+ ACE_NEW_RETURN (w,
+ EC_Wrapper,
+ w);
+ return w;
+}
+
+EC_Wrapper::~EC_Wrapper (void)
+{
+ ACE_TRY_NEW_ENV
+ {
+ this->destroy_ec (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ // ignore
+ }
+ ACE_ENDTRY;
+}
+
+int
+EC_Wrapper::init (CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa)
+{
+ if (CORBA::is_nil (orb)
+ || this->ec_impl_)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "EC_Wrapper::init invoked improperly\n"),
+ -1);
+ }
+
+ this->orb_ = CORBA::ORB::_duplicate (orb);
+
+ TAO_EC_Event_Channel_Attributes attr (poa, poa);
+
+ // Allow reconnections - used by some tests.
+ attr.consumer_reconnect = 1;
+
+ TAO_EC_Event_Channel * impl = 0;
+ ACE_NEW_RETURN (impl,
+ TAO_EC_Event_Channel (attr),
+ -1);
+ auto_ptr<TAO_EC_Event_Channel> impl_release (impl);
+
+ ACE_TRY_NEW_ENV
+ {
+ impl->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Suppressed the following exception "
+ "in EC_Wrapper::init:\n");
+ return -1;
+ }
+ ACE_ENDTRY;
+
+ this->ec_impl_ = impl_release.release ();
+ return 0;
+}
+
+RtecEventChannelAdmin::ConsumerAdmin_ptr
+EC_Wrapper::for_consumers (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (this->ec_impl_)
+ return this->ec_impl_->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ else
+ ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (), RtecEventChannelAdmin::ConsumerAdmin::_nil());
+}
+
+RtecEventChannelAdmin::SupplierAdmin_ptr
+EC_Wrapper::for_suppliers (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (this->ec_impl_)
+ return this->ec_impl_->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ else
+ ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (), RtecEventChannelAdmin::SupplierAdmin::_nil());
+}
+
+void
+EC_Wrapper::destroy_ec (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ auto_ptr<TAO_EC_Event_Channel> ec_impl_aptr (this->ec_impl_);
+ this->ec_impl_ = 0;
+
+ if (ec_impl_aptr.get ())
+ {
+ ec_impl_aptr->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+}
+
+void
+EC_Wrapper::destroy (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ // Deregister from POA.
+ this->deactivator_.deactivate ();
+
+ ACE_TRY
+ {
+ this->destroy_ec (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ this->orb_->shutdown ();
+ ACE_RE_THROW;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+
+ this->orb_->shutdown ();
+}
+
+RtecEventChannelAdmin::Observer_Handle
+EC_Wrapper::append_observer (RtecEventChannelAdmin::Observer_ptr observer
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((
+ CORBA::SystemException,
+ RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR,
+ RtecEventChannelAdmin::EventChannel::CANT_APPEND_OBSERVER))
+{
+ if (this->ec_impl_)
+ return this->ec_impl_->append_observer (observer ACE_ENV_ARG_PARAMETER);
+ else
+ ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (), 0);
+}
+
+void
+EC_Wrapper::remove_observer (RtecEventChannelAdmin::Observer_Handle handle
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((
+ CORBA::SystemException,
+ RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR,
+ RtecEventChannelAdmin::EventChannel::CANT_REMOVE_OBSERVER))
+{
+ if (this->ec_impl_)
+ this->ec_impl_->remove_observer (handle ACE_ENV_ARG_PARAMETER);
+ else
+ ACE_THROW (CORBA::OBJECT_NOT_EXIST ());
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Common/EC_Wrapper.h b/TAO/orbsvcs/tests/Event/Mcast/Common/EC_Wrapper.h
new file mode 100644
index 00000000000..20031f40dc1
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Common/EC_Wrapper.h
@@ -0,0 +1,97 @@
+/* -*- C++ -*- */
+// $Id$
+
+#ifndef EC_WRAPPER_H
+#define EC_WRAPPER_H
+
+#include "orbsvcs/RtecEventChannelAdminS.h"
+#include "orbsvcs/Event/EC_Lifetime_Utils_T.h"
+#include "ECMcastTests_export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+class TAO_EC_Event_Channel;
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class EC_Wrapper
+ *
+ * @brief This class decorates Rtec Event Channel implementation:
+ * - destroy () also shutdowns the ORB
+ * - automatic cleanup in destructor, if necessary
+ */
+class ECMcastTests_Export EC_Wrapper:
+ public virtual POA_RtecEventChannelAdmin::EventChannel,
+ public TAO_EC_Deactivated_Object
+{
+public:
+
+ /// Create a new EC_Wrapper object.
+ /// (Constructor access is restricted to insure that all
+ /// EC_Wrapper objects are heap-allocated.)
+ static TAO_EC_Servant_Var<EC_Wrapper> create (void);
+
+ /// Destructor. Destroys the Event Channel implementation.
+ virtual ~EC_Wrapper (void);
+
+ /// Create and initialize underlying EC servant.
+ int init (CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa);
+
+ /// RtecEventChannelAdmin::Event_Channel methods.
+ //@{
+ virtual RtecEventChannelAdmin::ConsumerAdmin_ptr
+ for_consumers (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ virtual RtecEventChannelAdmin::SupplierAdmin_ptr
+ for_suppliers (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// Destroy the Event Channel, deactivate from POA, and shut down
+ /// the ORB.
+ virtual void destroy (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ virtual RtecEventChannelAdmin::Observer_Handle
+ append_observer (RtecEventChannelAdmin::Observer_ptr observer
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((
+ CORBA::SystemException,
+ RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR,
+ RtecEventChannelAdmin::EventChannel::CANT_APPEND_OBSERVER));
+ virtual void remove_observer (RtecEventChannelAdmin::Observer_Handle
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((
+ CORBA::SystemException,
+ RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR,
+ RtecEventChannelAdmin::EventChannel::CANT_REMOVE_OBSERVER));
+ //@}
+
+protected:
+
+ /// Constructor (protected). Clients can create new
+ /// EC_Wrapper objects using the static create() method.
+ EC_Wrapper (void);
+
+private:
+
+ /// Helper - destroys Event Channel and deactivate from POA, if
+ /// necessary.
+ void destroy_ec (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// Event Channel implementation.
+ /*
+ * Once Event Channel implementation is made reference-counted, this
+ * pointer should turn into a Servant_Var.
+ */
+ TAO_EC_Event_Channel *ec_impl_;
+
+ /// A reference to the ORB, so we can shut it down.
+ CORBA::ORB_var orb_;
+};
+
+#endif /* EC_WRAPPER_H */
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Common/Gateway_EC.cpp b/TAO/orbsvcs/tests/Event/Mcast/Common/Gateway_EC.cpp
new file mode 100644
index 00000000000..667ac9e8efb
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Common/Gateway_EC.cpp
@@ -0,0 +1,162 @@
+// $Id$
+
+#include "Gateway_EC.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+#include "orbsvcs/Event/ECG_Mcast_Gateway.h"
+#include "orbsvcs/Event/EC_Lifetime_Utils_T.h"
+#include "ace/Get_Opt.h"
+#include "ace/Dynamic_Service.h"
+#include "ace/OS_NS_stdio.h"
+
+Gateway_EC::Gateway_EC (void)
+ : ec_ior_file_ ("gateway-ec.ior")
+{
+}
+
+int
+Gateway_EC::check_for_nil (CORBA::Object_ptr obj, const char *message)
+{
+ if (CORBA::is_nil (obj))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ERROR: Object reference <%s> is nil\n",
+ message),
+ -1);
+ else
+ return 0;
+}
+
+int
+Gateway_EC::parse_args (int argc, char *argv [])
+{
+ ACE_Get_Opt get_opt (argc, argv, "i:");
+ int opt;
+
+ while ((opt = get_opt ()) != EOF)
+ {
+ switch (opt)
+ {
+ case 'i':
+ this->ec_ior_file_ = get_opt.optarg;
+ break;
+
+ case '?':
+ default:
+ ACE_DEBUG ((LM_DEBUG,
+ "Usage: %s "
+ "-i ior_file_name"
+ "\n",
+ argv[0]));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+void
+Gateway_EC::write_ior_file (CORBA::ORB_ptr orb,
+ RtecEventChannelAdmin::EventChannel_ptr ec
+ ACE_ENV_ARG_DECL)
+{
+ // Write EC ior to a file.
+ CORBA::String_var str;
+ str = orb->object_to_string (ec ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ FILE *output_file= ACE_OS::fopen (this->ec_ior_file_, "w");
+ if (output_file == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "Cannot open output file for writing IOR: %s",
+ this->ec_ior_file_));
+ ACE_THROW (CORBA::INTERNAL ());
+ }
+
+ ACE_OS::fprintf (output_file, "%s", str.in ());
+ ACE_OS::fclose (output_file);
+}
+
+int
+Gateway_EC::run (int argc, char ** argv)
+{
+ // Event Channel Configuration.
+ TAO_EC_Default_Factory::init_svcs ();
+ // Mcast gateway configuration.
+ TAO_ECG_Mcast_Gateway::init_svcs ();
+
+ TAO_EC_ORB_Holder orb_destroyer;
+
+ ACE_TRY_NEW_ENV
+ {
+ // Initialize ORB and POA, POA Manager, parse args.
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ orb_destroyer.init (orb);
+
+ if (parse_args (argc, argv) == -1)
+ return -1;
+
+ CORBA::Object_var obj =
+ orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ PortableServer::POA_var poa =
+ PortableServer::POA::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ if (check_for_nil (poa.in (), "POA") == -1)
+ return -1;
+ PortableServer::POAManager_var manager =
+ poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Set up EC.
+ TAO_EC_Servant_Var<EC_Wrapper> ec_wrapper (EC_Wrapper::create ());
+ if (!ec_wrapper.in ())
+ return -1;
+
+ if (ec_wrapper->init (orb.in (),
+ poa.in ()) != 0)
+ return -1;
+
+ RtecEventChannelAdmin::EventChannel_var ec;
+ TAO_EC_Object_Deactivator ec_deactivator;
+ activate (ec,
+ poa.in (),
+ ec_wrapper.in (),
+ ec_deactivator
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ ec_wrapper->set_deactivator (ec_deactivator);
+
+ this->write_ior_file (orb.in (), ec.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Set up multicast components.
+ // Obtain mcast gateway from service configurator.
+ TAO_ECG_Mcast_Gateway * gateway = 0;
+ gateway =
+ ACE_Dynamic_Service<TAO_ECG_Mcast_Gateway>::instance ("ECG_Mcast_Gateway");
+
+ if (!gateway)
+ {
+ ACE_TRY_THROW (CORBA::INTERNAL ());
+ ACE_TRY_CHECK;
+ }
+ gateway->run (orb.in (), ec.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Run server.
+ orb->run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Unexpected Exception in Gateway EC:");
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Common/Gateway_EC.h b/TAO/orbsvcs/tests/Event/Mcast/Common/Gateway_EC.h
new file mode 100644
index 00000000000..1db97bc26de
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Common/Gateway_EC.h
@@ -0,0 +1,50 @@
+/* -*- C++ -*- */
+// $Id$
+
+#ifndef GATEWAY_EC_H
+#define GATEWAY_EC_H
+
+#include "EC_Wrapper.h"
+#include "ECMcastTests_export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class Gateway_EC
+ *
+ * @brief Runs multicast federated Event Channel server.
+ *
+ * Runs Event Channel and mcast receiver and/or sender (as specified
+ * in service config file).
+ */
+class ECMcastTests_Export Gateway_EC
+{
+public:
+
+ /// Constructor.
+ Gateway_EC (void);
+
+ /// Run the server.
+ /// Valid arguments: [-i ior_filename].
+ int run (int argc, char ** argv);
+
+private:
+
+ /// Helpers.
+ //@{
+ int parse_args (int argc, char *argv[]);
+ int check_for_nil (CORBA::Object_ptr obj, const char *message);
+ void write_ior_file (CORBA::ORB_ptr orb,
+ RtecEventChannelAdmin::EventChannel_ptr ec
+ ACE_ENV_ARG_DECL);
+ //@}
+
+ /// Event Channel ior is written to this file.
+ /// Default is "gateway-ec.ior", which can be overridden with the "-i"
+ /// argument option.
+ const char * ec_ior_file_;
+};
+
+#endif /* GATEWAY_EC_H */
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Common/Makefile.am b/TAO/orbsvcs/tests/Event/Mcast/Common/Makefile.am
new file mode 100644
index 00000000000..27940a1cb2b
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Common/Makefile.am
@@ -0,0 +1,51 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## ../bin/mwc.pl -type automake -noreldefs TAO.mwc
+
+ACE_BUILDDIR = $(top_builddir)/..
+ACE_ROOT = $(top_srcdir)/..
+TAO_BUILDDIR = $(top_builddir)
+TAO_ROOT = $(top_srcdir)
+
+
+## Makefile.ECMcastTests_lib.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_LTLIBRARIES = libECMcastTests.la
+
+libECMcastTests_la_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -DECMCASTTESTS_BUILD_DLL
+
+libECMcastTests_la_SOURCES = \
+ EC_Wrapper.cpp \
+ Gateway_EC.cpp
+
+noinst_HEADERS = \
+ ECMcastTests_export.h \
+ EC_Wrapper.h \
+ Gateway_EC.h
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Complex/Complex.mpc b/TAO/orbsvcs/tests/Event/Mcast/Complex/Complex.mpc
new file mode 100644
index 00000000000..ee053554cb1
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Complex/Complex.mpc
@@ -0,0 +1,53 @@
+// -*- MPC -*-
+// $Id$
+
+project(*supplier): messaging, rteventexe, rtevent_serv, naming {
+ after += ECMcastTests_lib
+ libs += ECMcastTests
+
+ specific (automake) {
+ includes += $(srcdir)/../Common
+ } else {
+ includes += ../Common
+ }
+
+ exename = supplier
+
+ Source_Files {
+ supplier.cpp
+ }
+}
+
+project(*consumer): messaging, rteventexe, rtevent_serv, naming {
+ after += ECMcastTests_lib
+ libs += ECMcastTests
+
+ specific (automake) {
+ includes += $(srcdir)/../Common
+ } else {
+ includes += ../Common
+ }
+
+ exename = consumer
+
+ Source_Files {
+ consumer.cpp
+ }
+}
+
+project(*gateway-ec): messaging, rteventexe, rtevent_serv, naming {
+ after += ECMcastTests_lib
+ libs += ECMcastTests
+
+ specific (automake) {
+ includes += $(srcdir)/../Common
+ } else {
+ includes += ../Common
+ }
+
+ exename = gateway-ec
+
+ Source_Files {
+ gateway-ec.cpp
+ }
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Complex/Constants.h b/TAO/orbsvcs/tests/Event/Mcast/Complex/Constants.h
new file mode 100644
index 00000000000..bc1faae8c3b
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Complex/Constants.h
@@ -0,0 +1,9 @@
+// $Id$
+
+#include "orbsvcs/Event_Service_Constants.h"
+
+#define A_EVENT_TYPE ACE_ES_EVENT_UNDEFINED+1
+#define B_EVENT_TYPE A_EVENT_TYPE+1
+#define C_EVENT_TYPE B_EVENT_TYPE+1
+
+#define SOURCE_ID ACE_ES_EVENT_SOURCE_ANY+1
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Complex/Makefile.am b/TAO/orbsvcs/tests/Event/Mcast/Complex/Makefile.am
new file mode 100644
index 00000000000..1b52b4fb3bd
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Complex/Makefile.am
@@ -0,0 +1,141 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## ../bin/mwc.pl -type automake -noreldefs TAO.mwc
+
+ACE_BUILDDIR = $(top_builddir)/..
+ACE_ROOT = $(top_srcdir)/..
+TAO_BUILDDIR = $(top_builddir)
+TAO_ROOT = $(top_srcdir)
+
+noinst_PROGRAMS =
+
+## Makefile.Complex_Consumer.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += consumer
+
+consumer_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../Common
+
+consumer_SOURCES = \
+ consumer.cpp \
+ Constants.h
+
+consumer_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/Mcast/Common/libECMcastTests.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Complex_Gateway_Ec.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += gateway-ec
+
+gateway_ec_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../Common
+
+gateway_ec_SOURCES = \
+ gateway-ec.cpp \
+ Constants.h
+
+gateway_ec_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/Mcast/Common/libECMcastTests.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Complex_Supplier.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += supplier
+
+supplier_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../Common
+
+supplier_SOURCES = \
+ supplier.cpp \
+ Constants.h
+
+supplier_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/Mcast/Common/libECMcastTests.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Complex/README b/TAO/orbsvcs/tests/Event/Mcast/Complex/README
new file mode 100644
index 00000000000..e0000644dc7
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Complex/README
@@ -0,0 +1,55 @@
+// $Id$
+
+Goals:
+------
+This is a step up from the Simple mcast test. There are still two
+Event Channels participating: one sends out its events via multicast,
+while the second one listens for events on multicast.
+
+But this test uses ECG_Mcast_Gateway configured with Complex
+Address Server and Complex Mcast Handler components. In other words,
+different types of events are sent to different multicast addresses,
+requiring an interested Event Channel to subscribe to all groups carrying
+events of interest to its consumers.
+
+Description:
+------------
+There are three executables: event supplier, event consumer,
+and federation-enabled Event Channel, of which we run two instances -
+one for supplier and one for consumer. Federated Channels are
+configured to use a different mcast group for each event type.
+Supplier pushes 100 events of each of the three event types to its
+Event Channel while the consumer waits for events from its EC. Once
+the consumer receives 100 events of each of the three types it
+expects, it destroys its EC and exits.
+
+Command-line Options:
+---------------------
+Consumer: $consumer -ORBInitRef Event_Service=<ior>
+
+Supplier: $supplier -ORBInitRef Event_Service=<ior>
+
+Mcast-equipped EC: $gateway_ec -ORBsvcconf <conf_file> -i <ior_file>
+where
+<ior_file> is the name of the file to which the ior of the Event
+ Channel will be printed
+<conf_file> is a service conf file used to configure the Event Channel
+ and the multicast components. See consumer-ec.conf or
+ supplier-ec.conf for examples, or
+ $TAO_ROOT/orbsvcs/orbsvcs/Event/ECG_Mcast_Gateway.h for
+ all valid multicast configuration options.
+
+To run:
+-------
+Automagically (runs all executables, processes output):
+$ run_test.pl
+
+Manually:
+$gateway-ec -ORBsvcconf consumer-ec.conf -i consumer-ec.ior
+$consumer -ORBInitRef Event_Service=file://consumer-ec.ior
+$gateway-ec -ORBsvcconf supplier-ec.conf -i supplier-ec.ior
+$supplier -ORBInitRef Event_Service=file://supplier-ec.ior
+
+
+
+
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Complex/consumer-ec.conf b/TAO/orbsvcs/tests/Event/Mcast/Complex/consumer-ec.conf
new file mode 100644
index 00000000000..fefd2eec034
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Complex/consumer-ec.conf
@@ -0,0 +1,3 @@
+# $Id$
+static EC_Factory "-ECObserver basic -ECfiltering basic -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"
+static ECG_Mcast_Gateway "-ECGService receiver -ECGHandler complex -ECGAddressServer type -ECGAddressServerArg '17@230.100.0.7:12700 18@230.100.0.8:12700 19@230.100.0.9:12700'"
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Complex/consumer.cpp b/TAO/orbsvcs/tests/Event/Mcast/Complex/consumer.cpp
new file mode 100644
index 00000000000..390b0a14f09
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Complex/consumer.cpp
@@ -0,0 +1,229 @@
+// $Id$
+
+#include "Constants.h"
+#include "orbsvcs/Event/EC_Lifetime_Utils_T.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/RtecEventChannelAdminC.h"
+#include "orbsvcs/RtecEventCommS.h"
+
+class EC_Consumer:
+ public POA_RtecEventComm::PushConsumer
+{
+public:
+
+ /// Constructor.
+ EC_Consumer (CORBA::ORB_var orb,
+ RtecEventChannelAdmin::EventChannel_var ec);
+
+ /// PushConsumer methods.
+ //@{
+ /// Logs each event. Initiates shutdown after receiving 100 events
+ /// of each type.
+ virtual void push (const RtecEventComm::EventSet &events
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// No-op.
+ virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+private:
+
+ /// Helper - destroys EC, shutdowns the ORB and prints number of
+ /// events received.
+ void disconnect (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// Number of events of different types pushed to us by EC.
+ //@{
+ size_t a_events_;
+ size_t b_events_;
+ size_t c_events_;
+ //@}
+
+ /// Cache these pointers for cleanup.
+ CORBA::ORB_var orb_;
+ RtecEventChannelAdmin::EventChannel_var ec_;
+};
+
+EC_Consumer::EC_Consumer (CORBA::ORB_var orb,
+ RtecEventChannelAdmin::EventChannel_var ec)
+ : a_events_ (0),
+ b_events_ (0),
+ c_events_ (0),
+ orb_ (orb),
+ ec_ (ec)
+{
+}
+
+void
+EC_Consumer::push (const RtecEventComm::EventSet &events
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ for (CORBA::ULong i = 0; i < events.length (); ++i)
+ {
+ switch (events[i].header.type)
+ {
+ case A_EVENT_TYPE:
+ ++this->a_events_;
+ ACE_DEBUG ((LM_DEBUG, " Received event A\n"));
+ break;
+
+ case B_EVENT_TYPE:
+ ++this->b_events_;
+ ACE_DEBUG ((LM_DEBUG, " Received event B\n"));
+ break;
+
+ case C_EVENT_TYPE:
+ ++this->c_events_;
+ ACE_DEBUG ((LM_DEBUG, " Received event C\n"));
+ break;
+
+ default:
+ ACE_DEBUG ((LM_DEBUG, " Received event of UNKNOWN event type\n"));
+ }
+ }
+
+ if (this->a_events_ >= 100
+ && this->b_events_ >= 100
+ && this->c_events_ >= 100)
+ this->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+}
+
+void
+EC_Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+}
+
+void
+EC_Consumer::disconnect (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (this->a_events_ == 100
+ && this->b_events_ == 100
+ && this->c_events_ == 100)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "SUCCESS:\n"
+ " Received 100 events of each type "
+ "(A, B, and C), as expected\n"));
+ }
+
+ this->ec_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->orb_->shutdown (0 ACE_ENV_ARG_PARAMETER);
+}
+
+////////////////////////////////////////////////////////////
+int
+check_for_nil (CORBA::Object_ptr obj, const char *message)
+{
+ if (CORBA::is_nil (obj))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ERROR: Object reference <%s> is nil\n",
+ message),
+ -1);
+ else
+ return 0;
+}
+
+int
+parse_args (int /* argc */, char ** /* argv */)
+{
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ ACE_TRY_NEW_ENV
+ {
+ // Initialize ORB and POA, POA Manager, parse args.
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (parse_args (argc, argv) == -1)
+ return 1;
+
+ CORBA::Object_var obj =
+ orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ PortableServer::POA_var poa =
+ PortableServer::POA::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ if (check_for_nil (poa.in (), "POA") == -1)
+ return 1;
+
+ PortableServer::POAManager_var manager =
+ poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain reference to EC.
+ obj = orb->resolve_initial_references ("Event_Service" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ RtecEventChannelAdmin::EventChannel_var ec =
+ RtecEventChannelAdmin::EventChannel::_narrow (obj.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ if (check_for_nil (ec.in (), "EC") == -1)
+ return 1;
+
+ // Create the consumer and register it with POA.
+ TAO_EC_Servant_Var<EC_Consumer> consumer_impl =
+ new EC_Consumer (orb, ec);
+
+ if (!consumer_impl.in ())
+ return -1;
+
+ RtecEventComm::PushConsumer_var consumer;
+ TAO_EC_Object_Deactivator consumer_deactivator;
+ activate (consumer,
+ poa.in (),
+ consumer_impl.in (),
+ consumer_deactivator
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ consumer_deactivator.disallow_deactivation ();
+
+ // Obtain reference to ConsumerAdmin.
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ ec->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain ProxyPushSupplier and connect this consumer.
+ RtecEventChannelAdmin::ProxyPushSupplier_var supplier =
+ consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_ConsumerQOS_Factory qos;
+ qos.start_disjunction_group (3);
+ qos.insert_type (A_EVENT_TYPE, 0);
+ qos.insert_type (B_EVENT_TYPE, 0);
+ qos.insert_type (C_EVENT_TYPE, 0);
+ supplier->connect_push_consumer (consumer.in (),
+ qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Allow processing of CORBA requests.
+ manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Receive events from EC.
+ orb->run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Exception in Consumer:");
+ return 1;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Complex/gateway-ec.cpp b/TAO/orbsvcs/tests/Event/Mcast/Complex/gateway-ec.cpp
new file mode 100644
index 00000000000..7ab5ff9b030
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Complex/gateway-ec.cpp
@@ -0,0 +1,13 @@
+// $Id$
+
+#include "Gateway_EC.h"
+
+int
+main (int argc, char ** argv)
+{
+ Gateway_EC test;
+ if (test.run (argc, argv) == -1)
+ return 1;
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Complex/run_test.pl b/TAO/orbsvcs/tests/Event/Mcast/Complex/run_test.pl
new file mode 100755
index 00000000000..cfd2aece892
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Complex/run_test.pl
@@ -0,0 +1,215 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+# This is a Perl script that runs Simple EC Mcast example. It starts
+# consumer, supplier and two (federated) Event Channel servers.
+# See README for more details.
+
+use lib '../../../../../../bin';
+use PerlACE::Run_Test;
+use POSIX;
+
+###############################################################
+# Configuration parameters
+###############################################################
+
+# Amount of delay (in seconds) between starting a server and a client
+# to allow proper server initialization.
+$sleeptime = 10;
+
+# Variables for command-line arguments to client and server
+# executables.
+$consumer_iorfile = PerlACE::LocalFile ("consumer-ec.ior");
+$supplier_iorfile = PerlACE::LocalFile ("supplier-ec.ior");
+$consumer_conffile = PerlACE::LocalFile ("consumer-ec.conf");
+$supplier_conffile = PerlACE::LocalFile ("supplier-ec.conf");
+
+
+#################################################################
+# Subs
+#################################################################
+
+sub run_test
+{
+ # Supplier EC.
+ if (run_ec (0, $supplier_conffile, $supplier_iorfile) != 0) {
+ kill_processes (); return -1;
+ }
+
+ # Consumer EC.
+ if (run_ec (1, $consumer_conffile, $consumer_iorfile) != 0) {
+ kill_processes (); return -1;
+ }
+
+ # Consumer.
+ $ps[2] =
+ new PerlACE::Process ("consumer",
+ "-ORBInitRef Event_Service=file://$consumer_iorfile");
+ if ($ps[2]->Spawn () == -1) {
+ kill_processes (); return -1;
+ }
+
+ # Give consumer a chance to connect to its EC before firing off the supplier.
+ sleep ($sleeptime);
+
+ # Supplier.
+ $ps[3] =
+ new PerlACE::Process ("supplier",
+ "-ORBInitRef Event_Service=file://$supplier_iorfile");
+ if ($ps[3]->Spawn () == -1) {
+ kill_processes (); return -1;
+ }
+
+ # Shutdown.
+ return kill_processes ();
+}
+
+# Start Event Channel server.
+sub run_ec
+{
+ my $ec_id = $_[0];
+ my $conf_file = $_[1];
+ my $ior_file = $_[2];
+
+ unlink $ior_file;
+
+ $ps[$ec_id] = new PerlACE::Process ("gateway-ec",
+ "-ORBsvcconf $conf_file -i $ior_file");
+ if ($ps[$ec_id]->Spawn () == -1) {
+ return 1;
+ }
+
+ if (PerlACE::waitforfile_timed ($ior_file, $sleeptime) == -1)
+ {
+ print STDERR "ERROR: cannot find IOR file <$ior_file>\n";
+ $ps[$ec_id]->Kill ();
+ return 1;
+ }
+
+ return 0;
+}
+
+# Wait for and kill, if necessary, all started processes.
+sub kill_processes
+{
+ my $result = 0;
+
+ foreach $p (@ps)
+ {
+ if ($p->WaitKill (60) != 0) {
+ $result = -1;
+ }
+ }
+
+ if ($result == -1) {
+ print STDERR "ERROR detected\n";
+ return -1;
+ }
+
+ return 0;
+}
+
+sub restore_output
+{
+ # Restore output facilities.
+ close (STDERR);
+ close (STDOUT);
+ open (STDOUT, ">&OLDOUT");
+ open (STDERR, ">&OLDERR");
+}
+
+sub redirect_output
+{
+ my $rundate = POSIX::strftime("%Y_%m_%d_%H_%M", localtime);
+ $output_file = PerlACE::LocalFile ("run_test_$rundate");
+
+ open (OLDOUT, ">&STDOUT");
+ open (STDOUT, ">$output_file") or die "can't redirect stdout: $!";
+ open (OLDERR, ">&STDERR");
+ open (STDERR, ">&STDOUT") or die "can't redirect stderror: $!";
+}
+
+sub analyze_results
+{
+ if (! open (TEST_OUTPUT, "<$output_file"))
+ {
+ print STDERR "ERROR: Could not open $output_file\n";
+ return -1;
+ }
+
+ my $status = 0;
+ my $a_events = 0;
+ my $b_events = 0;
+ my $c_events = 0;
+ while (<TEST_OUTPUT>)
+ {
+ if (m/Received event A/)
+ {
+ $a_events += 1;
+ }
+ elsif (m/Received event B/)
+ {
+ $b_events += 1;
+ }
+ elsif (m/Received event C/)
+ {
+ $c_events += 1;
+ }
+ elsif (m/Received 100 events/
+ || m/SUCCESS/)
+ {
+ #skip this line - we do our own counting.
+ }
+ else
+ {
+ print STDERR $_;
+ $status = -1;
+ }
+ }
+ close (TEST_OUTPUT);
+
+ my $all_received = 1;
+ if ($a_events != 100
+ || $b_events != 100
+ || $c_events != 100)
+ {
+ $all_received = 0;
+ print STDERR "ERROR: consumer received\n"
+ ."\t$a_events A events, expected 100\n"
+ ."\t$b_events B events, expected 100\n"
+ ."\t$c_events C events, expected 100\n";
+ }
+
+ if ($all_received && $status == 0) {
+ print STDERR "SUCCESS\n";
+ return 0;
+ }
+
+ print STDERR "ERROR - check $output_file for full output.\n";
+ return -1;
+}
+
+##############################################################
+# Run executables.
+##############################################################
+
+$status = 0;
+
+redirect_output ();
+
+if (run_test () == -1) {
+ $status = 1;
+}
+
+restore_output ();
+
+if (analyze_results () == -1) {
+ $status = 1;
+}
+
+exit $status;
+
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Complex/supplier-ec.conf b/TAO/orbsvcs/tests/Event/Mcast/Complex/supplier-ec.conf
new file mode 100644
index 00000000000..7135b8f4957
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Complex/supplier-ec.conf
@@ -0,0 +1,3 @@
+# $Id$
+static EC_Factory "-ECfiltering basic -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"
+static ECG_Mcast_Gateway "-ECGService sender -ECGAddressServer type -ECGAddressServerArg '17@230.100.0.7:12700 18@230.100.0.8:12700 19@230.100.0.9:12700'"
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Complex/supplier.cpp b/TAO/orbsvcs/tests/Event/Mcast/Complex/supplier.cpp
new file mode 100644
index 00000000000..ab13f1a28ef
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Complex/supplier.cpp
@@ -0,0 +1,120 @@
+// $Id$
+
+#include "Constants.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/RtecEventCommC.h"
+#include "orbsvcs/RtecEventChannelAdminC.h"
+#include "ace/Log_Msg.h"
+
+void
+send_events (RtecEventChannelAdmin::ProxyPushConsumer_ptr consumer
+ ACE_ENV_ARG_DECL)
+{
+ // Events we'll send.
+ RtecEventComm::EventSet events (1);
+ events.length (1);
+ // Events travelling through gateways must have a ttl count of at
+ // least 1!
+ events[0].header.ttl = 1;
+ events[0].header.source = SOURCE_ID;
+
+ for (int i = 0; i < 100; ++i)
+ {
+ // Send 1 event of each type.
+ events[0].header.type = A_EVENT_TYPE;
+ consumer->push (events ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ events[0].header.type = B_EVENT_TYPE;
+ consumer->push (events ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ events[0].header.type = C_EVENT_TYPE;
+ consumer->push (events ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+}
+
+int
+check_for_nil (CORBA::Object_ptr obj, const char *message)
+{
+ if (CORBA::is_nil (obj))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ERROR: Object reference <%s> is nil\n",
+ message),
+ -1);
+ else
+ return 0;
+}
+
+int
+parse_args (int /*argc*/, char ** /*argv*/)
+{
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ // Initialize ORB and parse args.
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (parse_args (argc, argv) == -1)
+ return 1;
+
+ // Obtain reference to EC.
+ CORBA::Object_var obj =
+ orb->resolve_initial_references ("Event_Service" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ RtecEventChannelAdmin::EventChannel_var ec =
+ RtecEventChannelAdmin::EventChannel::_narrow (obj.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ if (check_for_nil (ec.in (), "EC") == -1)
+ return 1;
+
+ // Obtain reference to SupplierAdmin.
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ ec->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain ProxyPushConsumer and connect this supplier.
+ RtecEventChannelAdmin::ProxyPushConsumer_var consumer =
+ supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_SupplierQOS_Factory qos;
+ qos.insert (SOURCE_ID, A_EVENT_TYPE, 0, 1);
+ qos.insert (SOURCE_ID, B_EVENT_TYPE, 0, 1);
+ qos.insert (SOURCE_ID, C_EVENT_TYPE, 0, 1);
+
+ consumer->connect_push_supplier
+ (RtecEventComm::PushSupplier::_nil (),
+ qos.get_SupplierQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Send events to EC.
+ send_events (consumer.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Tell EC to shut down.
+ ec->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Exception in Supplier:");
+ return 1;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Makefile.am b/TAO/orbsvcs/tests/Event/Mcast/Makefile.am
new file mode 100644
index 00000000000..8633ab9fcef
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Makefile.am
@@ -0,0 +1,16 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## ../bin/mwc.pl -type automake -noreldefs TAO.mwc
+
+SUBDIRS = \
+ Common \
+ Complex \
+ Simple \
+ Two_Way
+
diff --git a/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventConsumerMain.cpp b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventConsumerMain.cpp
new file mode 100644
index 00000000000..077d4505c1a
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventConsumerMain.cpp
@@ -0,0 +1,109 @@
+// $Id$
+
+// EchoEventConsumerMain.cpp
+// Main program for a PushConsumer of Echo events.
+
+#include "EchoEventConsumer_i.h"
+
+#include <orbsvcs/RtecEventCommC.h>
+#include <orbsvcs/RtecEventChannelAdminC.h>
+#include <orbsvcs/Time_Utilities.h>
+#include <orbsvcs/Event_Utilities.h>
+#include <orbsvcs/CosNamingC.h>
+
+#include <iostream>
+const RtecEventComm::EventSourceID MY_SOURCE_ID = ACE_ES_EVENT_SOURCE_ANY + 1;
+const RtecEventComm::EventType MY_EVENT_TYPE = ACE_ES_EVENT_UNDEFINED + 1;
+
+const int EVENT_LIMIT = 20;
+
+int main (int argc, char* argv[])
+{
+ try
+ {
+ // Initialize the ORB.
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
+
+ const char* ecname = "EventService";
+ for (int i = 0; argv[i] != 0; i++) {
+ if (strcmp(argv[i], "-ecname") == 0) {
+ if (argv[i+1] != 0) {
+ ecname = argv[i+1];
+ } else {
+ std::cerr << "Missing Event channel name" << std::endl;
+ }
+ }
+ }
+
+ // Find the Naming Service.
+ CORBA::Object_var obj = orb->resolve_initial_references("NameService");
+ CosNaming::NamingContextExt_var root_context = CosNaming::NamingContextExt::_narrow(obj.in());
+
+ // Find the EchoEventChannel.
+ obj = root_context->resolve_str(ecname);
+
+ // Downcast the object reference to an EventChannel reference.
+ RtecEventChannelAdmin::EventChannel_var ec =
+ RtecEventChannelAdmin::EventChannel::_narrow(obj.in());
+ if (CORBA::is_nil(ec.in())) {
+ std::cerr << "Could not narrow EchoEventChannel." << std::endl;
+ return 1;
+ }
+ std::cout << "EchoEventConsumerMain.cpp: Found the EchoEventChannel." << std::endl;
+
+ // Obtain a reference to the consumer administration object.
+ RtecEventChannelAdmin::ConsumerAdmin_var admin = ec->for_consumers();
+
+ // Obtain a reference to the push supplier proxy.
+ RtecEventChannelAdmin::ProxyPushSupplier_var supplier =
+ admin->obtain_push_supplier();
+
+ // Get the RootPOA.
+ obj = orb->resolve_initial_references("RootPOA");
+ PortableServer::POA_var poa = PortableServer::POA::_narrow(obj.in());
+
+ // Instantiate an EchoEventConsumer_i servant.
+ EchoEventConsumer_i servant(orb.in(), EVENT_LIMIT);
+
+ // Register it with the RootPOA.
+ PortableServer::ObjectId_var oid = poa->activate_object(&servant);
+ CORBA::Object_var consumer_obj = poa->id_to_reference(oid.in());
+ RtecEventComm::PushConsumer_var consumer =
+ RtecEventComm::PushConsumer::_narrow(consumer_obj.in());
+
+ // Connect as a consumer.
+ ACE_ConsumerQOS_Factory qos;
+ qos.start_disjunction_group ();
+ qos.insert (MY_SOURCE_ID, // Source ID
+ MY_EVENT_TYPE, // Event Type
+ 0); // handle to the rt_info
+ supplier->connect_push_consumer (consumer.in (),
+ qos.get_ConsumerQOS ());
+
+ // Activate the POA via its POAManager.
+ PortableServer::POAManager_var poa_manager = poa->the_POAManager();
+ poa_manager->activate();
+
+ std::cout << "EchoEventConsumerMain.cpp: Ready to receive events..." << std::endl;
+
+ // Enter the ORB event loop.
+ orb->run();
+
+ // If we have reached this, we must be shutting down...
+ // Disconnect the ProxyPushSupplier.
+ //supplier->disconnect_push_supplier();
+ //supplier = RtecEventChannelAdmin::ProxyPushSupplier::_nil();
+ //admin = RtecEventChannelAdmin::ConsumerAdmin::_nil();
+
+ orb->destroy();
+
+ return 0;
+
+ }
+ catch (CORBA::Exception& exc)
+ {
+ std::cerr << "Caught CORBA::Exception" << std::endl << exc << std::endl;
+ }
+
+ return 1;
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventConsumer_i.cpp b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventConsumer_i.cpp
new file mode 100644
index 00000000000..68515ac1a09
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventConsumer_i.cpp
@@ -0,0 +1,54 @@
+// $Id$
+
+// EchoEventConsumer_i.cpp
+// Implements a PushConsumer.
+
+#include "EchoEventConsumer_i.h"
+#include "tao/PortableServer/PS_CurrentC.h"
+#include "ace/OS_NS_stdio.h"
+
+#include <sstream>
+
+// Constructor duplicates the ORB reference.
+EchoEventConsumer_i::EchoEventConsumer_i(CORBA::ORB_ptr orb, int event_limit)
+ : orb_(CORBA::ORB::_duplicate(orb))
+ , event_limit_(event_limit)
+{
+ // Nothing to do.
+}
+
+// Implement the push() operation.
+void EchoEventConsumer_i::push(const RtecEventComm::EventSet& events)
+ throw(CORBA::SystemException)
+{
+ // Loop through the events, looking for shutdown events.
+ for (u_int i = 0; i < events.length (); ++i) {
+ //ACE_OS::printf(".");
+ // Extract event data from the any.
+ const char* eventData;
+ std::ostringstream out;
+ out << "Received event,"
+ << " type: " << events[i].header.type
+ << " source: " << events[i].header.source;
+ if (events[i].data.any_value >>= eventData) {
+ out << " text: " << eventData;
+ }
+
+ ACE_OS::printf("%s\n", out.str().c_str()); // printf is synchronized
+ }
+ if (--event_limit_ <= 0) {
+ orb_->shutdown(0);
+ }
+}
+
+// Implement the disconnect_push_consumer() operation.
+void EchoEventConsumer_i::disconnect_push_consumer()
+ throw(CORBA::SystemException)
+{
+ // Deactivate this object.
+ CORBA::Object_var obj = orb_->resolve_initial_references("POACurrent");
+ PortableServer::Current_var current = PortableServer::Current::_narrow(obj.in());
+ PortableServer::POA_var poa = current->get_POA();
+ PortableServer::ObjectId_var objectId = current->get_object_id();
+ poa->deactivate_object(objectId.in());
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventConsumer_i.h b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventConsumer_i.h
new file mode 100644
index 00000000000..f9f0f6168e5
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventConsumer_i.h
@@ -0,0 +1,29 @@
+// $Id$
+
+// EchoEventConsumer_i.h
+// Implements a PushConsumer.
+
+#ifndef _EchoEventConsumer_i_h_
+#define _EchoEventConsumer_i_h_
+
+#include <orbsvcs/RtecEventCommS.h> // for POA_CosEventComm::PushConsumer
+
+class EchoEventConsumer_i : public virtual POA_RtecEventComm::PushConsumer
+{
+ public:
+ // Constructor
+ EchoEventConsumer_i(CORBA::ORB_ptr orb, int event_limit);
+
+ // Override operations from PushConsumer interface.
+ virtual void push(const RtecEventComm::EventSet& events)
+ throw(CORBA::SystemException);
+
+ virtual void disconnect_push_consumer()
+ throw(CORBA::SystemException);
+
+ private:
+ CORBA::ORB_var orb_;
+ int event_limit_;
+};
+
+#endif // _EchoEventConsumer_i_h_
diff --git a/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventSupplierMain.cpp b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventSupplierMain.cpp
new file mode 100644
index 00000000000..316493b3f4c
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventSupplierMain.cpp
@@ -0,0 +1,245 @@
+// $Id$
+
+// EchoEventSupplierMain.cpp
+// Main program for a PushSupplier of Echo events.
+
+#include "EchoEventSupplier_i.h"
+#include "SimpleAddressServer.h"
+
+#include "orbsvcs/RtecEventCommC.h"
+#include "orbsvcs/RtecEventChannelAdminC.h"
+#include "orbsvcs/Time_Utilities.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/CosNamingC.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+#include "orbsvcs/Event/ECG_Mcast_EH.h"
+#include "orbsvcs/Event/ECG_UDP_Sender.h"
+#include "orbsvcs/Event/ECG_UDP_Receiver.h"
+#include "orbsvcs/Event/ECG_UDP_Out_Endpoint.h"
+#include "orbsvcs/Event/ECG_UDP_EH.h"
+
+#include "tao/ORB_Core.h"
+
+#include "ace/Auto_Ptr.h"
+#include <iostream>
+#include <fstream>
+
+const RtecEventComm::EventSourceID MY_SOURCE_ID = ACE_ES_EVENT_SOURCE_ANY + 1;
+const RtecEventComm::EventType MY_EVENT_TYPE = ACE_ES_EVENT_UNDEFINED + 1;
+
+const int EVENT_DELAY_MS = 10;
+
+int main (int argc, char* argv[])
+{
+ try
+ {
+ // Initialize the EC Factory so we can customize the EC
+ TAO_EC_Default_Factory::init_svcs ();
+
+ // Initialize the ORB.
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
+
+ const char* ecname = "EventService";
+ const char* address = "localhost";
+ const char* iorfile = 0;
+ u_short port = 12345;
+ u_short listenport = 12345;
+ int mcast = 1;
+
+ for (int i = 0; argv[i] != 0; i++) {
+ if (strcmp(argv[i], "-ecname") == 0) {
+ if (argv[i+1] != 0) {
+ i++;
+ ecname = argv[i];
+ } else {
+ std::cerr << "Missing Event channel name" << std::endl;
+ }
+ } else if (strcmp(argv[i], "-address") == 0) {
+ if (argv[i+1] != 0) {
+ i++;
+ address = argv[i];
+ } else {
+ std::cerr << "Missing address" << std::endl;
+ }
+ } else if (strcmp(argv[i], "-port") == 0) {
+ if (argv[i+1] != 0) {
+ i++;
+ port = ACE_OS::atoi(argv[i]);
+ } else {
+ std::cerr << "Missing port" << std::endl;
+ }
+ } else if (strcmp(argv[i], "-listenport") == 0) {
+ if (argv[i+1] != 0) {
+ i++;
+ listenport = ACE_OS::atoi(argv[i]);
+ } else {
+ std::cerr << "Missing port" << std::endl;
+ }
+ } else if (strcmp(argv[i], "-iorfile") == 0) {
+ if (argv[i+1] != 0) {
+ i++;
+ iorfile = argv[i];
+ }
+ } else if (strcmp(argv[i], "-udp") == 0) {
+ mcast = 0;
+ }
+ }
+
+ // Get the POA
+ CORBA::Object_var object = orb->resolve_initial_references ("RootPOA");
+ PortableServer::POA_var poa = PortableServer::POA::_narrow (object.in ());
+ PortableServer::POAManager_var poa_manager = poa->the_POAManager ();
+ poa_manager->activate ();
+
+ // Create a local event channel and register it
+ TAO_EC_Event_Channel_Attributes attributes (poa.in (), poa.in ());
+ TAO_EC_Event_Channel ec_impl (attributes);
+ ec_impl.activate ();
+ PortableServer::ObjectId_var oid = poa->activate_object(&ec_impl);
+ CORBA::Object_var ec_obj = poa->id_to_reference(oid.in());
+ RtecEventChannelAdmin::EventChannel_var ec =
+ RtecEventChannelAdmin::EventChannel::_narrow(ec_obj.in());
+
+ // Find the Naming Service.
+ CORBA::Object_var obj = orb->resolve_initial_references("NameService");
+ CosNaming::NamingContextExt_var root_context = CosNaming::NamingContextExt::_narrow(obj.in());
+
+ // Bind the Event Channel using Naming Services
+ CosNaming::Name_var name = root_context->to_name(ecname);
+ root_context->rebind(name.in(), ec.in());
+
+ // Get a proxy push consumer from the EventChannel.
+ RtecEventChannelAdmin::SupplierAdmin_var admin = ec->for_suppliers();
+ RtecEventChannelAdmin::ProxyPushConsumer_var consumer =
+ admin->obtain_push_consumer();
+
+ // Instantiate an EchoEventSupplier_i servant.
+ EchoEventSupplier_i servant(orb.in());
+
+ // Register it with the RootPOA.
+ oid = poa->activate_object(&servant);
+ CORBA::Object_var supplier_obj = poa->id_to_reference(oid.in());
+ RtecEventComm::PushSupplier_var supplier =
+ RtecEventComm::PushSupplier::_narrow(supplier_obj.in());
+
+ // Connect to the EC.
+ ACE_SupplierQOS_Factory qos;
+ qos.insert (MY_SOURCE_ID, MY_EVENT_TYPE, 0, 1);
+ consumer->connect_push_supplier (supplier.in (), qos.get_SupplierQOS ());
+
+ // Initialize the address server with the desired address.
+ // This will be used by the sender object and the multicast
+ // receiver.
+ ACE_INET_Addr send_addr (port, address);
+ SimpleAddressServer addr_srv_impl (send_addr);
+
+ PortableServer::ObjectId_var addr_srv_oid =
+ poa->activate_object(&addr_srv_impl);
+ CORBA::Object_var addr_srv_obj = poa->id_to_reference(addr_srv_oid.in());
+ RtecUDPAdmin::AddrServer_var addr_srv =
+ RtecUDPAdmin::AddrServer::_narrow(addr_srv_obj.in());
+
+ // Create and initialize the sender object
+ TAO_EC_Servant_Var<TAO_ECG_UDP_Sender> sender =
+ TAO_ECG_UDP_Sender::create();
+ TAO_ECG_UDP_Out_Endpoint endpoint;
+ if (endpoint.dgram ().open (ACE_Addr::sap_any) == -1) {
+ std::cerr << "Cannot open send endpoint" << std::endl;
+ return 1;
+ }
+
+ // TAO_ECG_UDP_Sender::init() takes a TAO_ECG_Refcounted_Endpoint.
+ // If we don't clone our endpoint and pass &endpoint, the sender will
+ // attempt to delete endpoint during shutdown.
+ TAO_ECG_UDP_Out_Endpoint* clone;
+ ACE_NEW_RETURN (clone,
+ TAO_ECG_UDP_Out_Endpoint (endpoint),
+ -1);
+ sender->init (ec.in (), addr_srv.in (), clone);
+
+ // Setup the subscription and connect to the EC
+ ACE_ConsumerQOS_Factory cons_qos_fact;
+ cons_qos_fact.start_disjunction_group ();
+ cons_qos_fact.insert (ACE_ES_EVENT_SOURCE_ANY, ACE_ES_EVENT_ANY, 0);
+ RtecEventChannelAdmin::ConsumerQOS sub = cons_qos_fact.get_ConsumerQOS ();
+ sender->connect (sub);
+
+ // Create and initialize the receiver
+ TAO_EC_Servant_Var<TAO_ECG_UDP_Receiver> receiver =
+ TAO_ECG_UDP_Receiver::create();
+
+ // TAO_ECG_UDP_Receiver::init() takes a TAO_ECG_Refcounted_Endpoint.
+ // If we don't clone our endpoint and pass &endpoint, the receiver will
+ // attempt to delete endpoint during shutdown.
+ ACE_NEW_RETURN (clone,
+ TAO_ECG_UDP_Out_Endpoint (endpoint),
+ -1);
+ receiver->init (ec.in (), clone, addr_srv.in ());
+
+ // Setup the registration and connect to the event channel
+ ACE_SupplierQOS_Factory supp_qos_fact;
+ supp_qos_fact.insert (MY_SOURCE_ID, MY_EVENT_TYPE, 0, 1);
+ RtecEventChannelAdmin::SupplierQOS pub = supp_qos_fact.get_SupplierQOS ();
+ receiver->connect (pub);
+
+ // Create the appropriate event handler and register it with the reactor
+ auto_ptr<ACE_Event_Handler> eh;
+ if (mcast) {
+ auto_ptr<TAO_ECG_Mcast_EH> mcast_eh(new TAO_ECG_Mcast_EH (receiver.in()));
+ mcast_eh->reactor (orb->orb_core ()->reactor ());
+ mcast_eh->open (ec.in());
+ ACE_AUTO_PTR_RESET(eh,mcast_eh.release(),ACE_Event_Handler);
+ //eh.reset(mcast_eh.release());
+ } else {
+ auto_ptr<TAO_ECG_UDP_EH> udp_eh (new TAO_ECG_UDP_EH (receiver.in()));
+ udp_eh->reactor (orb->orb_core ()->reactor ());
+ ACE_INET_Addr local_addr (listenport);
+ if (udp_eh->open (local_addr) == -1) {
+ std::cerr << "Cannot open EH" << std::endl;
+ }
+ ACE_AUTO_PTR_RESET(eh,udp_eh.release(),ACE_Event_Handler);
+ //eh.reset(udp_eh.release());
+ }
+
+ // Create an event (just a string in this case).
+ const CORBA::String_var eventData = CORBA::string_dup(ecname);
+
+ // Create an event set for one event
+ RtecEventComm::EventSet event (1);
+ event.length (1);
+
+ // Initialize event header.
+ event[0].header.source = MY_SOURCE_ID;
+ event[0].header.ttl = 1;
+ event[0].header.type = MY_EVENT_TYPE;
+
+ // Initialize data fields in event.
+ event[0].data.any_value <<= eventData;
+
+ if (iorfile != 0) {
+ CORBA::String_var str = orb->object_to_string( ec.in() );
+ std::ofstream iorFile( iorfile );
+ iorFile << str.in() << std::endl;
+ iorFile.close();
+ }
+ std::cout << "Starting main loop" << std::endl;
+
+ const int EVENT_DELAY_MS = 10;
+
+ while (1) {
+ consumer->push (event);
+
+ ACE_Time_Value tv(0, 1000 * EVENT_DELAY_MS);
+ orb->run(tv);
+ }
+
+ orb->destroy();
+ return 0;
+ }
+ catch (CORBA::Exception& exc)
+ {
+ std::cerr << "Caught CORBA::Exception" << std::endl << exc << std::endl;
+ }
+ return 1;
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventSupplier_i.cpp b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventSupplier_i.cpp
new file mode 100644
index 00000000000..be8c74dbe2e
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventSupplier_i.cpp
@@ -0,0 +1,26 @@
+// $Id$
+
+// EchoEventSupplier_i.cpp
+// Implements a PushSupplier.
+
+#include "EchoEventSupplier_i.h"
+#include "tao/PortableServer/PS_CurrentC.h"
+
+// Constructor duplicates the ORB reference.
+EchoEventSupplier_i::EchoEventSupplier_i(CORBA::ORB_ptr orb)
+ : orb_(CORBA::ORB::_duplicate(orb))
+{
+ // Nothing to do.
+}
+
+// Override the disconnect_push_Supplier() operation.
+void EchoEventSupplier_i::disconnect_push_supplier()
+ throw(CORBA::SystemException)
+{
+ // Deactivate this object.
+ CORBA::Object_var obj = orb_->resolve_initial_references("POACurrent");
+ PortableServer::Current_var current = PortableServer::Current::_narrow(obj.in());
+ PortableServer::POA_var poa = current->get_POA();
+ PortableServer::ObjectId_var objectId = current->get_object_id();
+ poa->deactivate_object(objectId.in());
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventSupplier_i.h b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventSupplier_i.h
new file mode 100644
index 00000000000..53f74aeea45
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/EchoEventSupplier_i.h
@@ -0,0 +1,24 @@
+// $Id$
+
+// EchoEventSupplier_i.h
+// Implements a PushSupplier.
+
+#ifndef _EchoEventSupplier_i_h_
+#define _EchoEventSupplier_i_h_
+
+#include <orbsvcs/RtecEventCommS.h> // for POA_CosEventComm::PushSupplier
+
+class EchoEventSupplier_i : public virtual POA_RtecEventComm::PushSupplier
+{
+ public:
+ // Constructor
+ EchoEventSupplier_i(CORBA::ORB_ptr orb);
+
+ virtual void disconnect_push_supplier()
+ throw(CORBA::SystemException);
+
+ private:
+ CORBA::ORB_var orb_;
+};
+
+#endif // _EchoEventSupplier_i_h_
diff --git a/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/README b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/README
new file mode 100644
index 00000000000..548f8a03a48
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/README
@@ -0,0 +1,138 @@
+Real-Time Event Service
+
+
+File: TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/README
+
+
+This directory contains an example that shows how to create and
+federate real-time event channels using the classes in EC_Gateway_UDP.h.
+Depending on the options, it will use either UDP or multicast to link
+the event channels.
+
+-------------------------------------------------------------------------
+
+Note: To run this example, you must first run the Naming Service, e.g.:
+
+ $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service -o ns.ior&
+
+-------------------------------------------------------------------------
+
+To start the supplier/EC processes on a single host and federate them
+using UDP, do the following (after starting the Naming_Service):
+
+ ./EchoEventSupplier -ORBInitRef NameService=file://ns.ior -udp -ecname name1 -port 1233 -listenport 1234
+ ./EchoEventSupplier -ORBInitRef NameService=file://ns.ior -udp -ecname name2 -port 1234 -listenport 1233
+
+This will start two EC/supplier processes on the same node. One (name1)
+will listen on port 1234 and send on port 1233. The other (name2) will
+do the opposite. You should be able to use any available port as long as
+the port and listenport options are symmetric (listenport of one process
+must be the port of the other). The -address option can be used to
+specify a supplier/EC process on another host. Here is an example of two
+processes on different hosts:
+
+On node1:
+ ./EchoEventSupplier -ORBInitRef NameService=file://ns.ior -udp -ecname name1 -port 1233 -listenport 1234 -address node2
+On node2:
+ ./EchoEventSupplier -ORBInitRef NameService=file://ns.ior -udp -ecname name2 -port 1234 -listenport 1233 -address node1
+
+When using UDP, this example is limited to federating two ECs.
+
+-------------------------------------------------------------------------
+
+To start the supplier/EC processes and federate them using multicast, do the
+following (after starting the Naming_Service):
+
+./EchoEventSupplier -ORBInitRef NameService=file://ns.ior -ORBSvcConf supplier.conf -ecname name1 -address 224.9.9.2 -port 1234
+./EchoEventSupplier -ORBInitRef NameService=file://ns.ior -ORBSvcConf supplier.conf -ecname name2 -address 224.9.9.2 -port 1234
+
+The -address and -port options should be passed a valid and available
+multicast address and port.
+
+-------------------------------------------------------------------------
+
+To start the consumers, simply do the following (this works the same for
+both types of federations):
+
+./EchoEventConsumer -ORBInitRef NameService=file://ns.ior -ecname name1
+./EchoEventConsumer -ORBInitRef NameService=file://ns.ior -ecname name2
+
+It may be easiest to start these in separate windows. Each consumer
+connects to one EC (specified by the -ecname option). You should see
+events from both suppliers on each event channel (each supplier passes
+events containing with the name of the EC they are using).
+
+-------------------------------------------------------------------------
+
+EchoEventSupplerMain.cpp
+
+ Main program for a PushSupplier.
+
+ EchoEventSupplier [ -ORBSvcConf supplier.conf ] [ -udp ] -ecname <name>
+ [ -address <address> ] [ -port <port> ]
+ [ -listenport <lport> ]
+
+ This will create a local RTEC event channel and bind it under
+ the root context of the naming service with the name <name>.
+ It will also federate with remote event channels specified via
+ the other options. By default, it uses multicast to federate
+ the ECs (specifying -udp forces use of UDP). <address> is
+ the address of the remote EC when using UDP and the multicast
+ address when using multicast. <port> is the port to send
+ to when using UDP and the multicast port when using multicast.
+ <lport> is the port to listen on for UDP (and not used by
+ multicast. You must pass -ORBSvcConf supplier.conf when
+ using multicast so as to enable Observers.
+
+ After initializing the local event channel and setting up the
+ connection for the federation, it publishes an event to the
+ local event channel every 10 milliseconds. This event will
+ contain the string <name> in the any_value field.
+
+ Use Control-C to kill the process.
+
+-------------------------------------------------------------------------
+
+EchoEventConsumerMain.cpp
+
+ Main program for a PushConsumer.
+
+ To run it:
+
+ EchoEventConsumer -ecname <name>
+
+ This will look for an event channel bound to <name> in the Root context
+ of the Naming Service. It will consume events from this channel and
+ print the type, source, and string contents contained in any_value.
+
+ Use Control-C to kill the process.
+
+-------------------------------------------------------------------------
+
+EchoEventConsumer_i.{h,cpp}
+
+ Call which implements the RtecEventComm::PushConsumer interface.
+
+-------------------------------------------------------------------------
+
+SimpleAddressServer.{h,cpp}
+
+ This is a servant class that implements the RtecUDPAdmin::AddrServer
+ interface. It is used by the UDP/multicast senders to return an
+ address that they will send out particular events on. It is also
+ used by the multicast event handler, to determine which addresses
+ to listen to based on consumer subscriptions. This simple
+ implementation always returns the same address.
+
+
+
+Exeuction via Perl Script
+-------------------------
+
+A Perl script has been created to automate the steps shown
+above. This script can be run via the following command:
+
+./run_test.pl
+
+By default, this script uses multicast; pass -udp to the
+script to use udp.
diff --git a/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/RTEC_MCast_Federated.mpc b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/RTEC_MCast_Federated.mpc
new file mode 100644
index 00000000000..6910d790a5d
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/RTEC_MCast_Federated.mpc
@@ -0,0 +1,25 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Supplier): namingexe, rteventexe, rtevent_serv {
+ requires += exceptions
+ exename = EchoEventSupplier
+ includes += ../common
+
+ Source_Files {
+ EchoEventSupplierMain.cpp
+ EchoEventSupplier_i.cpp
+ SimpleAddressServer.cpp
+ }
+}
+
+project(*Consumer): namingexe, rteventexe, {
+ requires += exceptions
+ exename = EchoEventConsumer
+ includes += ../common
+
+ Source_Files {
+ EchoEventConsumerMain.cpp
+ EchoEventConsumer_i.cpp
+ }
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/SimpleAddressServer.cpp b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/SimpleAddressServer.cpp
new file mode 100644
index 00000000000..9007b31369a
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/SimpleAddressServer.cpp
@@ -0,0 +1,18 @@
+// $Id$
+
+// SimpleAddressServer.cpp
+
+#include "SimpleAddressServer.h"
+#include <ace/INET_Addr.h>
+
+SimpleAddressServer::SimpleAddressServer (const ACE_INET_Addr& address) {
+ this->address_.ipaddr = address.get_ip_address ();
+ this->address_.port = address.get_port_number ();
+}
+
+void
+SimpleAddressServer::get_addr (const RtecEventComm::EventHeader&,
+ RtecUDPAdmin::UDP_Addr& address)
+ throw (CORBA::SystemException) {
+ address = this->address_;
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/SimpleAddressServer.h b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/SimpleAddressServer.h
new file mode 100644
index 00000000000..5c2c92454c6
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/SimpleAddressServer.h
@@ -0,0 +1,25 @@
+// $Id$
+
+// SimpleAddressServer.h
+
+#ifndef SIMPLEADDRESSSERVER_H
+#define SIMPLEADDRESSSERVER_H
+
+#include <orbsvcs/RtecUDPAdminS.h>
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+class ACE_INET_Addr;
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+class SimpleAddressServer : public POA_RtecUDPAdmin::AddrServer {
+public:
+ SimpleAddressServer (const ACE_INET_Addr& address);
+ virtual void get_addr (const RtecEventComm::EventHeader& header,
+ RtecUDPAdmin::UDP_Addr& address)
+ throw (CORBA::SystemException);
+
+private:
+ RtecUDPAdmin::UDP_Addr address_;
+};
+
+#endif
diff --git a/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/run_test.pl b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/run_test.pl
new file mode 100755
index 00000000000..1a1135c596b
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/run_test.pl
@@ -0,0 +1,142 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+use Env (ACE_ROOT);
+use lib "$ACE_ROOT/bin";
+use PerlACE::Run_Test;
+
+sub usage() {
+ print "Usage:\n";
+ print " run_test [-h] [-debug]\n\n";
+ print " -udp -- Federate using udp\n";
+ print " -mcast -- Federate using multicast (the default)\n";
+ print " -h -- Prints this information\n";
+ print " -debug -- Sets the debug flag for the test\n";
+ exit;
+}
+
+my $udp = 0;
+my $i = 0;
+my $flags = "";
+while ($i <= $#ARGV) {
+ if ($ARGV[$i] eq "-h" || $ARGV[$i] eq "-help" ||
+ $ARGV[$i] eq "--help" || $ARGV[$i] eq "-?") {
+ usage ();
+ } elsif ($ARGV[$i] eq "-debug") {
+ $flags .= " -ORBDebugLevel 10 ";
+ } elsif ($ARGV[$i] eq "-udp") {
+ $udp = 1;
+ } elsif ($ARGV[$i] eq "-mcast") {
+ $udp = 0;
+ } else {
+ print "ERROR: Unknown Option: ".$ARGV[$i]."\n\n";
+ usage ();
+ }
+ $i++;
+}
+
+if ($udp) {
+ print "Using UDP to link the event channels.\n\n";
+} else {
+ print "Using multicast to link the event channels.\n\n";
+}
+
+$nsiorfile = PerlACE::LocalFile ("ns.ior");
+$ec1iorfile = PerlACE::LocalFile ("ec1.ior");
+$ec2iorfile = PerlACE::LocalFile ("ec2.ior");
+
+$arg_ns_ref = "-ORBInitRef NameService=file://$nsiorfile";
+$end_point = "-ORBEndpoint iiop://localhost";
+
+unlink $nsiorfile;
+unlink $ec1iorfile;
+unlink $ec2iorfile;
+
+# start Naming Service
+
+$NameService = "$ENV{TAO_ROOT}/orbsvcs/Naming_Service/Naming_Service";
+$NS = new PerlACE::Process($NameService, "$flags -o $nsiorfile $end_point:2809");
+$NS->Spawn();
+if (PerlACE::waitforfile_timed ($nsiorfile, 5) == -1) {
+ print STDERR "ERROR: cannot find file <$nsiorfile>\n";
+ $NS->Kill();
+ exit 1;
+}
+
+# start EchoEventSupplier
+my($port1) = 10001 + PerlACE::uniqueid() ;
+my($port2) = 10001 + PerlACE::uniqueid() ;
+my($mport) = 10001 + PerlACE::uniqueid() ;
+if ( -e "supplier.conf" )
+{
+ $supplier_conf_file = "supplier.conf";
+}
+else{
+ $supplier_conf_file = "../supplier.conf";
+}
+
+$args1 = "$flags $arg_ns_ref -ORBSvcConf $supplier_conf_file $end_point -iorfile $ec1iorfile";
+if ($udp) {
+ $args1 .= " -udp -ecname ec1 -port $port1 -listenport $port2 ";
+} else {
+ $args1 .= " -ecname ec1 -address 224.9.9.2 -port $mport ";
+}
+$S1 = new PerlACE::Process("EchoEventSupplier", $args1);
+$S1->Spawn();
+
+$args2 = "$flags $arg_ns_ref -ORBSvcConf $supplier_conf_file $end_point -iorfile $ec2iorfile";
+if ($udp) {
+ $args2 .= " -udp -ecname ec2 -port $port2 -listenport $port1 ";
+} else {
+ $args2 .= " -ecname ec2 -address 224.9.9.2 -port $mport ";
+}
+$S2 = new PerlACE::Process("EchoEventSupplier", $args2);
+$S2->Spawn();
+
+if ((PerlACE::waitforfile_timed ($ec1iorfile, 10) == -1) ||
+ (PerlACE::waitforfile_timed ($ec2iorfile, 2) == -1)) {
+ print STDERR "ERROR: cannot find files <$ec1iorfile> and <$ec2iorfile>\n";
+ $NS->Kill();
+ $S1->Kill();
+ $S2->Kill();
+ exit 1;
+}
+
+$args3 = "$flags $arg_ns_ref -ecname ec1 $end_point";
+$C1 = new PerlACE::Process("EchoEventConsumer", $args3);
+$C1->Spawn();
+
+
+$args4 = "$flags $arg_ns_ref -ecname ec2 $end_point";
+$C2 = new PerlACE::Process("EchoEventConsumer", $args4);
+$C2->Spawn();
+
+if ($C1->WaitKill(30) == -1) {
+ $S1->Kill();
+ $S2->Kill();
+ $NS->Kill();
+ $C2->Kill();
+
+ exit 1;
+}
+
+if ($C2->WaitKill(5) == -1) {
+ $S1->Kill();
+ $S2->Kill();
+ $NS->Kill();
+ exit 1;
+}
+
+$NS->Kill();
+$S1->Kill();
+$S2->Kill();
+
+unlink $nsiorfile;
+unlink $ec1iorfile;
+unlink $ec2iorfile;
+
+exit 0;
diff --git a/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/supplier.conf b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/supplier.conf
new file mode 100644
index 00000000000..d9eeea24f43
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/RTEC_MCast_Federated/supplier.conf
@@ -0,0 +1,2 @@
+# $Id$
+static EC_Factory "-ECobserver basic"
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Simple/Constants.h b/TAO/orbsvcs/tests/Event/Mcast/Simple/Constants.h
new file mode 100644
index 00000000000..45bca620bf2
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Simple/Constants.h
@@ -0,0 +1,6 @@
+// $Id$
+
+#include "orbsvcs/Event_Service_Constants.h"
+
+#define EVENT_TYPE ACE_ES_EVENT_UNDEFINED+1
+#define SOURCE_ID ACE_ES_EVENT_SOURCE_ANY+1
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Simple/Makefile.am b/TAO/orbsvcs/tests/Event/Mcast/Simple/Makefile.am
new file mode 100644
index 00000000000..617b25f0ec2
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Simple/Makefile.am
@@ -0,0 +1,141 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## ../bin/mwc.pl -type automake -noreldefs TAO.mwc
+
+ACE_BUILDDIR = $(top_builddir)/..
+ACE_ROOT = $(top_srcdir)/..
+TAO_BUILDDIR = $(top_builddir)
+TAO_ROOT = $(top_srcdir)
+
+noinst_PROGRAMS =
+
+## Makefile.Simple_Consumer.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += consumer
+
+consumer_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../Common
+
+consumer_SOURCES = \
+ consumer.cpp \
+ Constants.h
+
+consumer_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/Mcast/Common/libECMcastTests.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Simple_Gateway_Ec.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += gateway-ec
+
+gateway_ec_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../Common
+
+gateway_ec_SOURCES = \
+ gateway-ec.cpp \
+ Constants.h
+
+gateway_ec_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/Mcast/Common/libECMcastTests.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Simple_Supplier.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += supplier
+
+supplier_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../Common
+
+supplier_SOURCES = \
+ supplier.cpp \
+ Constants.h
+
+supplier_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/Mcast/Common/libECMcastTests.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Simple/README b/TAO/orbsvcs/tests/Event/Mcast/Simple/README
new file mode 100644
index 00000000000..14c87028fb3
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Simple/README
@@ -0,0 +1,62 @@
+// $Id$
+
+Goals:
+------
+This is the most basic test for federating Event Channels via
+multicast or udp. Two Event Channels participate: one sends out its events
+via multicast (or udp), while the second one listens for events on
+multicast (or udp).
+
+This test can be run with two different configurations: multicast is used
+for federating event channels in one and udp is used in another. The
+test uses ECG_Mcast_Gateway configured with Simple Address Server and
+Simple Mcast Handler or UDP Handler components.
+
+Description:
+------------
+There are three executables: event supplier, event consumer,
+and federation-enabled Event Channel, of which we run two instances -
+one for supplier and one for consumer.
+Supplier pushes 100 events to its Event Channel while the consumer
+waits for events from its EC. Once the consumer receives 100 events
+it expects, it destroys its EC and exits.
+
+Command-line Options:
+---------------------
+Consumer: $consumer -ORBInitRef Event_Service=<ior>
+
+Supplier: $supplier -ORBInitRef Event_Service=<ior>
+
+Mcast-equipped EC: $gateway_ec -ORBsvcconf <conf_file> -i <ior_file>
+where
+<ior_file> is the name of the file to which the ior of the Event
+ Channel will be printed
+<conf_file> is a service conf file used to configure the Event Channel
+ and the multicast components. See consumer-ec.conf or
+ supplier-ec.conf for examples, or
+ $TAO_ROOT/orbsvcs/orbsvcs/Event/ECG_Mcast_Gateway.h for
+ all valid multicast configuration options.
+
+To run:
+-------
+Automagically (runs all executables, processes output):
+$ run_test.pl
+
+Manually:
+
+ Multicast Federation test
+
+$gateway-ec -ORBsvcconf consumer-ec.conf -i consumer-ec.ior
+$consumer -ORBInitRef Event_Service=file://consumer-ec.ior
+$gateway-ec -ORBsvcconf supplier-ec.conf -i supplier-ec.ior
+$supplier -ORBInitRef Event_Service=file://supplier-ec.ior
+
+ UDP Federation test
+
+$gateway-ec -ORBsvcconf udp-consumer-ec.conf -i consumer-ec.ior
+$consumer -ORBInitRef Event_Service=file://consumer-ec.ior
+$gateway-ec -ORBsvcconf udp-supplier-ec.conf -i supplier-ec.ior
+$supplier -ORBInitRef Event_Service=file://supplier-ec.ior
+
+
+
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Simple/Simple.mpc b/TAO/orbsvcs/tests/Event/Mcast/Simple/Simple.mpc
new file mode 100644
index 00000000000..ee053554cb1
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Simple/Simple.mpc
@@ -0,0 +1,53 @@
+// -*- MPC -*-
+// $Id$
+
+project(*supplier): messaging, rteventexe, rtevent_serv, naming {
+ after += ECMcastTests_lib
+ libs += ECMcastTests
+
+ specific (automake) {
+ includes += $(srcdir)/../Common
+ } else {
+ includes += ../Common
+ }
+
+ exename = supplier
+
+ Source_Files {
+ supplier.cpp
+ }
+}
+
+project(*consumer): messaging, rteventexe, rtevent_serv, naming {
+ after += ECMcastTests_lib
+ libs += ECMcastTests
+
+ specific (automake) {
+ includes += $(srcdir)/../Common
+ } else {
+ includes += ../Common
+ }
+
+ exename = consumer
+
+ Source_Files {
+ consumer.cpp
+ }
+}
+
+project(*gateway-ec): messaging, rteventexe, rtevent_serv, naming {
+ after += ECMcastTests_lib
+ libs += ECMcastTests
+
+ specific (automake) {
+ includes += $(srcdir)/../Common
+ } else {
+ includes += ../Common
+ }
+
+ exename = gateway-ec
+
+ Source_Files {
+ gateway-ec.cpp
+ }
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Simple/consumer-ec.conf b/TAO/orbsvcs/tests/Event/Mcast/Simple/consumer-ec.conf
new file mode 100644
index 00000000000..838d1461384
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Simple/consumer-ec.conf
@@ -0,0 +1,4 @@
+# $Id$
+
+static EC_Factory "-ECfiltering basic -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"
+static ECG_Mcast_Gateway "-ECGService receiver -ECGAddressServerArg 230.100.1.7:26700"
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Simple/consumer.cpp b/TAO/orbsvcs/tests/Event/Mcast/Simple/consumer.cpp
new file mode 100644
index 00000000000..7b95c67318f
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Simple/consumer.cpp
@@ -0,0 +1,195 @@
+// $Id$
+
+#include "Constants.h"
+#include "orbsvcs/Event/EC_Lifetime_Utils_T.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/RtecEventChannelAdminC.h"
+#include "orbsvcs/RtecEventCommS.h"
+
+class EC_Consumer:
+ public POA_RtecEventComm::PushConsumer
+{
+public:
+
+ /// Constructor.
+ EC_Consumer (CORBA::ORB_var orb,
+ RtecEventChannelAdmin::EventChannel_var ec);
+
+ /// PushConsumer methods.
+ //@{
+ /// Logs each event. Initiates shutdown after receiving 100 events.
+ virtual void push (const RtecEventComm::EventSet &events
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ /// No-op.
+ virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ //@}
+
+private:
+
+ /// Helper - destroys EC, shutdowns the ORB and prints number of
+ /// events received.
+ void disconnect (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Number of events pushed to us by EC.
+ size_t n_events_;
+
+ /// Cache these pointers for cleanup.
+ CORBA::ORB_var orb_;
+ RtecEventChannelAdmin::EventChannel_var ec_;
+};
+
+EC_Consumer::EC_Consumer (CORBA::ORB_var orb,
+ RtecEventChannelAdmin::EventChannel_var ec)
+ : n_events_ (0),
+ orb_ (orb),
+ ec_ (ec)
+{
+}
+
+void
+EC_Consumer::push (const RtecEventComm::EventSet &events
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ for (CORBA::ULong i = 0; i < events.length (); ++i)
+ {
+ ++this->n_events_;
+ ACE_DEBUG ((LM_DEBUG, " Received event\n"));
+ }
+
+ if (this->n_events_ >= 100)
+ this->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+}
+
+void
+EC_Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+}
+
+void
+EC_Consumer::disconnect (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->n_events_ == 100)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "SUCCESS: consumer received 100 events, as expected\n"));
+ }
+
+ this->ec_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->orb_->shutdown (0 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+////////////////////////////////////////////////////////////
+int
+check_for_nil (CORBA::Object_ptr obj, const char *message)
+{
+ if (CORBA::is_nil (obj))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ERROR: Object reference <%s> is nil\n",
+ message),
+ -1);
+ else
+ return 0;
+}
+
+int
+parse_args (int /* argc */, char ** /* argv */)
+{
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ ACE_TRY_NEW_ENV
+ {
+ // Initialize ORB and POA, POA Manager, parse args.
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (parse_args (argc, argv) == -1)
+ return 1;
+
+ CORBA::Object_var obj =
+ orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ PortableServer::POA_var poa =
+ PortableServer::POA::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ if (check_for_nil (poa.in (), "POA") == -1)
+ return 1;
+
+ PortableServer::POAManager_var manager =
+ poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain reference to EC.
+ obj = orb->resolve_initial_references ("Event_Service" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ RtecEventChannelAdmin::EventChannel_var ec =
+ RtecEventChannelAdmin::EventChannel::_narrow (obj.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ if (check_for_nil (ec.in (), "EC") == -1)
+ return 1;
+
+ // Create the consumer and register it with POA.
+ TAO_EC_Servant_Var<EC_Consumer> consumer_impl =
+ new EC_Consumer (orb, ec);
+
+ if (!consumer_impl.in ())
+ return 1;
+
+ RtecEventComm::PushConsumer_var consumer;
+ TAO_EC_Object_Deactivator consumer_deactivator;
+ activate (consumer,
+ poa.in (),
+ consumer_impl.in (),
+ consumer_deactivator
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ consumer_deactivator.disallow_deactivation ();
+
+ // Obtain reference to ConsumerAdmin.
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ ec->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain ProxyPushSupplier and connect this consumer.
+ RtecEventChannelAdmin::ProxyPushSupplier_var supplier =
+ consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_ConsumerQOS_Factory qos;
+ qos.start_disjunction_group (1);
+ qos.insert_type (ACE_ES_EVENT_ANY, 0);
+ supplier->connect_push_consumer (consumer.in (),
+ qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Allow processing of CORBA requests.
+ manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Receive events from EC.
+ orb->run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Exception in Consumer:");
+ return 1;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Simple/gateway-ec.cpp b/TAO/orbsvcs/tests/Event/Mcast/Simple/gateway-ec.cpp
new file mode 100644
index 00000000000..462f226b0aa
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Simple/gateway-ec.cpp
@@ -0,0 +1,15 @@
+// $Id$
+
+#include "Gateway_EC.h"
+
+int
+main (int argc, char ** argv)
+{
+ Gateway_EC test;
+
+ if (test.run (argc, argv) == -1)
+ return 1;
+
+ return 0;
+}
+
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Simple/run_test.pl b/TAO/orbsvcs/tests/Event/Mcast/Simple/run_test.pl
new file mode 100755
index 00000000000..0bad2bd3a1f
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Simple/run_test.pl
@@ -0,0 +1,235 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+# This is a Perl script that runs Simple EC Mcast example. It starts
+# consumer, supplier and two (federated) Event Channel servers.
+# See README for more details.
+
+use lib '../../../../../../bin';
+use PerlACE::Run_Test;
+
+###############################################################
+# Configuration parameters
+###############################################################
+
+# String indicating end of test output.
+$test_terminator = "###########################################";
+
+# Amount of delay (in seconds) between starting a server and a client
+# to allow proper server initialization.
+$sleeptime = 10;
+
+# Variables for command-line arguments to client and server
+# executables.
+$consumer_iorfile = PerlACE::LocalFile ("consumer-ec.ior");
+$supplier_iorfile = PerlACE::LocalFile ("supplier-ec.ior");
+
+@consumer_conffile = (PerlACE::LocalFile ("consumer-ec.conf")
+ , PerlACE::LocalFile ("udp-consumer-ec.conf"));
+
+@supplier_conffile = (PerlACE::LocalFile ("supplier-ec.conf")
+ , PerlACE::LocalFile ("udp-supplier-ec.conf"));
+
+@test_comments =
+ ("Test 1: Mcast Handler",
+ "Test 2: UDP Handler");
+
+#################################################################
+# Subs
+#################################################################
+
+sub run_test
+{
+ my $index = shift;
+
+ print STDERR " $test_comments[$index]\n\n";
+
+ # Supplier EC.
+ if (run_ec (0, $supplier_conffile[$index], $supplier_iorfile) != 0) {
+ kill_processes (); return -1;
+ }
+
+ # Consumer EC.
+ if (run_ec (1, $consumer_conffile[$index], $consumer_iorfile) != 0) {
+ kill_processes (); return -1;
+ }
+
+ # Consumer.
+ $ps[2] =
+ new PerlACE::Process ("consumer",
+ "-ORBInitRef Event_Service=file://$consumer_iorfile");
+ if ($ps[2]->Spawn () == -1) {
+ kill_processes (); return -1;
+ }
+
+ # Give consumer a chance to connect to its EC before firing off the supplier.
+ sleep ($sleeptime);
+
+ # Supplier.
+ $ps[3] =
+ new PerlACE::Process ("supplier",
+ "-ORBInitRef Event_Service=file://$supplier_iorfile");
+ if ($ps[3]->Spawn () == -1) {
+ kill_processes (); return -1;
+ }
+
+ # Shutdown.
+ return kill_processes ();
+}
+
+# Start Event Channel server.
+sub run_ec
+{
+ my $ec_id = $_[0];
+ my $conf_file = $_[1];
+ my $ior_file = $_[2];
+
+ unlink $ior_file;
+
+ $ps[$ec_id] = new PerlACE::Process ("gateway-ec",
+ "-ORBsvcconf $conf_file -i $ior_file");
+ if ($ps[$ec_id]->Spawn () == -1) {
+ return 1;
+ }
+
+ if (PerlACE::waitforfile_timed ($ior_file, $sleeptime) == -1)
+ {
+ print STDERR "ERROR: cannot find IOR file <$ior_file>\n";
+ $ps[$ec_id]->Kill ();
+ return 1;
+ }
+
+ return 0;
+}
+
+# Wait for and kill, if necessary, all started processes.
+sub kill_processes
+{
+ my $result = 0;
+
+ foreach $p (@ps)
+ {
+ if ($p->WaitKill (60) != 0) {
+ $result = -1;
+ }
+ }
+
+ if ($result == -1) {
+ print STDERR "ERROR detected\n";
+ return -1;
+ }
+
+ return 0;
+}
+
+sub redirect_output
+{
+ my $rundate = POSIX::strftime("%Y_%m_%d_%H_%M", localtime);
+ $output_file = PerlACE::LocalFile ("run_test_$rundate");
+
+ open (OLDOUT, ">&STDOUT");
+ open (STDOUT, ">$output_file") or die "can't redirect stdout: $!";
+ open (OLDERR, ">&STDERR");
+ open (STDERR, ">&STDOUT") or die "can't redirect stderror: $!";
+}
+
+sub restore_output
+{
+ # Restore output facilities.
+ close (STDERR);
+ close (STDOUT);
+ open (STDOUT, ">&OLDOUT");
+ open (STDERR, ">&OLDERR");
+}
+
+sub analyze_results
+{
+ my $test_number = shift;
+ print STDERR " $test_comments[$test_number]\n\n";
+
+ if (! open (TEST_OUTPUT, "<$output_file"))
+ {
+ print STDERR "ERROR: Could not open $output_file\n";
+ return -1;
+ }
+
+ my $output_start = $test_comments[$test_number];
+ while (<TEST_OUTPUT>)
+ {
+ # Skip output not pertinent to this test.
+ last if m/\Q$output_start\E/;
+ }
+
+ my $status = 0;
+ my $events_received = 0;
+ while (<TEST_OUTPUT>)
+ {
+ last if m/$test_terminator/;
+
+ if (m/Received event/)
+ {
+ $events_received += 1;
+ }
+ elsif (m/consumer received 100 events/
+ || m/^\s+$/)
+ {
+ #skip this line - we do our own counting.
+ }
+ else
+ {
+ $status = -1;
+ print STDERR $_;
+ }
+ }
+ close (TEST_OUTPUT);
+
+ if ($events_received != 100)
+ {
+ print STDERR "ERROR: "
+ ."consumer received $events_received events, expected 100\n";
+ }
+
+ if ($events_received == 100 && $status == 0) {
+ print STDERR "SUCCESS\n";
+ return 0;
+ }
+
+ print STDERR "ERROR - check $output_file for full output.\n";
+ return -1;
+}
+
+##############################################################
+# Run executables.
+##############################################################
+
+$status = 0;
+
+redirect_output ();
+
+for ($i = 0; $i < 2; $i++)
+{
+ if (run_test ($i) == -1) {
+ $status = 1;
+ }
+
+ print STDERR "$test_terminator\n\n";
+}
+
+restore_output ();
+
+for ($i = 0; $i < 2; $i++)
+{
+ if (analyze_results ($i) == -1) {
+ $status = 1;
+ }
+
+ print STDERR "\n";
+}
+
+exit $status;
+
+
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Simple/supplier-ec.conf b/TAO/orbsvcs/tests/Event/Mcast/Simple/supplier-ec.conf
new file mode 100644
index 00000000000..7fe85696513
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Simple/supplier-ec.conf
@@ -0,0 +1,32 @@
+# $Id$
+
+static EC_Factory "-ECfiltering basic -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"
+static ECG_Mcast_Gateway "-ECGService sender -ECGAddressServerArg 230.100.1.7:26700"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Simple/supplier.cpp b/TAO/orbsvcs/tests/Event/Mcast/Simple/supplier.cpp
new file mode 100644
index 00000000000..d7d0b4f1973
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Simple/supplier.cpp
@@ -0,0 +1,107 @@
+// $Id$
+
+#include "Constants.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/RtecEventCommC.h"
+#include "orbsvcs/RtecEventChannelAdminC.h"
+#include "ace/Log_Msg.h"
+
+void
+send_events (RtecEventChannelAdmin::ProxyPushConsumer_ptr consumer
+ ACE_ENV_ARG_DECL)
+{
+ RtecEventComm::EventSet events (1);
+ events.length (1);
+ // Events travelling through gateways must have a ttl count of at
+ // least 1!
+ events[0].header.ttl = 1;
+ events[0].header.type = EVENT_TYPE;
+ events[0].header.source = SOURCE_ID;
+
+ for (int i = 0; i < 100; ++i)
+ {
+ consumer->push (events ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+}
+
+int
+check_for_nil (CORBA::Object_ptr obj, const char *message)
+{
+ if (CORBA::is_nil (obj))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ERROR: Object reference <%s> is nil\n",
+ message),
+ -1);
+ else
+ return 0;
+}
+
+int
+parse_args (int /*argc*/, char ** /*argv*/)
+{
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ ACE_TRY_NEW_ENV
+ {
+ // Initialize ORB and parse args.
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (parse_args (argc, argv) == -1)
+ return 1;
+
+ // Obtain reference to EC.
+ CORBA::Object_var obj =
+ orb->resolve_initial_references ("Event_Service" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ RtecEventChannelAdmin::EventChannel_var ec =
+ RtecEventChannelAdmin::EventChannel::_narrow (obj.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ if (check_for_nil (ec.in (), "EC") == -1)
+ return 1;
+
+ // Obtain reference to SupplierAdmin.
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ ec->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain ProxyPushConsumer and connect this supplier.
+ RtecEventChannelAdmin::ProxyPushConsumer_var consumer =
+ supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_SupplierQOS_Factory qos;
+ qos.insert (SOURCE_ID, EVENT_TYPE, 0, 1);
+
+ consumer->connect_push_supplier
+ (RtecEventComm::PushSupplier::_nil (),
+ qos.get_SupplierQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Send 100 events to EC.
+ send_events (consumer.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Tell EC to shut down.
+ ec->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Exception in Supplier:");
+ return 1;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Simple/udp-consumer-ec.conf b/TAO/orbsvcs/tests/Event/Mcast/Simple/udp-consumer-ec.conf
new file mode 100644
index 00000000000..334731adc75
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Simple/udp-consumer-ec.conf
@@ -0,0 +1,4 @@
+# $Id$
+
+static EC_Factory "-ECfiltering basic -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"
+static ECG_Mcast_Gateway "-ECGService receiver -ECGHandler udp -ECGAddressServerArg 127.0.0.1:27500"
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Simple/udp-supplier-ec.conf b/TAO/orbsvcs/tests/Event/Mcast/Simple/udp-supplier-ec.conf
new file mode 100644
index 00000000000..084dd36bf67
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Simple/udp-supplier-ec.conf
@@ -0,0 +1,32 @@
+# $Id$
+
+static EC_Factory "-ECfiltering basic -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"
+static ECG_Mcast_Gateway "-ECGService sender -ECGAddressServerArg 127.0.0.1:27500"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Two_Way/Constants.h b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/Constants.h
new file mode 100644
index 00000000000..6a6919f964d
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/Constants.h
@@ -0,0 +1,7 @@
+// $Id$
+
+#include "orbsvcs/Event_Service_Constants.h"
+
+#define HEARTBEAT ACE_ES_EVENT_UNDEFINED+1
+#define SOURCE_ID ACE_ES_EVENT_SOURCE_ANY+1
+#define HEARTBEATS_TO_SEND 50
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Two_Way/Makefile.am b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/Makefile.am
new file mode 100644
index 00000000000..9ad215d370a
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/Makefile.am
@@ -0,0 +1,102 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## ../bin/mwc.pl -type automake -noreldefs TAO.mwc
+
+ACE_BUILDDIR = $(top_builddir)/..
+ACE_ROOT = $(top_srcdir)/..
+TAO_BUILDDIR = $(top_builddir)
+TAO_ROOT = $(top_srcdir)
+
+noinst_PROGRAMS =
+
+## Makefile.Two_Way_Application.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += application
+
+application_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../Common
+
+application_SOURCES = \
+ application.cpp \
+ Constants.h
+
+application_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/Mcast/Common/libECMcastTests.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Two_Way_Gateway_Ec.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += gateway-ec
+
+gateway_ec_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../Common
+
+gateway_ec_SOURCES = \
+ gateway-ec.cpp \
+ Constants.h
+
+gateway_ec_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/Mcast/Common/libECMcastTests.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Two_Way/README b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/README
new file mode 100644
index 00000000000..33f62b9c323
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/README
@@ -0,0 +1,57 @@
+// $Id$
+
+Goals:
+------
+The goal of this test is to verify that federation of Event Channels
+using multicast works correctly. Unlike "Simple" and "Complex" tests,
+this test can have any number of Event Channels participating in the
+federation, and each participating Event Channel has a full duplex
+multicast communication, i.e., both sends and receives events via multicast.
+
+Description:
+------------
+There are two executables: federation-enabled Event Channel an
+application, which acts both as EC consumer and supplier. Any number
+of EC/application executable pairs can be started for running the test.
+
+Each application subscribes with its EC for heartbeat events, and,
+while listening, also pushes (at regular intervals) 50 heartbeat
+events to its EC. Each heartbeat event contains info identifying its
+source (hostname + process id). Applications keep track of all the heartbeat
+events they receive, and print out the summary before shutting down.
+
+Command-line Options:
+---------------------
+Application: $application -ORBInitRef Event_Service=<ior> [-d]
+where
+-d indicates that the application will destroy its Event Channel
+ before exiting. If each application has its own private Event
+ Channel, each should use this flag, to have all executables terminate
+ automatically. If more than one application is using the same
+ Event Channel, then only one of those applications should use "-d"
+ option.
+
+Mcast-equipped EC: $gateway_ec -ORBsvcconf <conf_file> -i <ior_file>
+where
+<ior_file> is the name of the file to which the ior of the Event
+ Channel will be printed
+<conf_file> is a service conf file used to configure the Event Channel
+ and the multicast components. See consumer-ec.conf or
+ supplier-ec.conf for examples, or
+ $TAO_ROOT/orbsvcs/orbsvcs/Event/ECG_Mcast_Gateway.h for
+ all valid multicast configuration options.
+
+To run:
+-------
+Automagically (runs three EC/application pairs):
+$ run_test.pl
+
+Manually:
+As many times as desired (using a different ior file name each time) do
+$gateway-ec -ORBsvcconf gateway.conf -i ec.ior
+$application -ORBInitRef Event_Service=file://ec.ior -d
+
+
+
+
+
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Two_Way/Two_Way.mpc b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/Two_Way.mpc
new file mode 100644
index 00000000000..48da30505d0
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/Two_Way.mpc
@@ -0,0 +1,36 @@
+// -*- MPC -*-
+// $Id$
+
+project(*application): messaging, rteventexe, rtevent_serv, naming {
+ after += ECMcastTests_lib
+ libs += ECMcastTests
+
+ specific (automake) {
+ includes += $(srcdir)/../Common
+ } else {
+ includes += ../Common
+ }
+
+ exename = application
+
+ Source_Files {
+ application.cpp
+ }
+}
+
+project(*gateway-ec): messaging, rteventexe, rtevent_serv, naming {
+ after += ECMcastTests_lib
+ libs += ECMcastTests
+
+ specific (automake) {
+ includes += $(srcdir)/../Common
+ } else {
+ includes += ../Common
+ }
+
+ exename = gateway-ec
+
+ Source_Files {
+ gateway-ec.cpp
+ }
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Two_Way/application.cpp b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/application.cpp
new file mode 100644
index 00000000000..ce7c85cdd95
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/application.cpp
@@ -0,0 +1,666 @@
+// $Id$
+
+#include "Constants.h"
+
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Event/EC_Lifetime_Utils_T.h"
+#include "orbsvcs/Event/ECG_UDP_Sender.h"
+#include "orbsvcs/Event/ECG_UDP_Receiver.h"
+
+#include "orbsvcs/RtecEventChannelAdminC.h"
+#include "orbsvcs/RtecEventCommS.h"
+
+#include "tao/ORB_Core.h"
+
+#include "ace/Array_Base.h"
+#include "ace/Get_Opt.h"
+#include "ace/Reactor.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/os_include/os_netdb.h"
+
+// Indicates whether this application is responsible for destroying
+// the Event Channel it's using upon exit.
+int destroy_ec_flag = 0;
+
+/**
+ * @class Heartbeat_Application
+ *
+ * @brief A simple application for testing federation of Event
+ * Channels via multicast.
+ *
+ * NOTE: Contains platform-specific code (event data), i.e.,
+ * might not work cross-platform.
+ *
+ * This class acts both as a receiver and a supplier of HEARTBEAT events
+ * to a multicast-federated Event Channel. After sending a prespecified
+ * number of heartbeat events, it prints out a summary about received
+ * heartbeats and shuts down.
+ */
+class Heartbeat_Application :
+ public POA_RtecEventComm::PushConsumer,
+ public TAO_EC_Deactivated_Object
+{
+public:
+
+ /// Constructor.
+ Heartbeat_Application (void);
+
+ /// Destructor.
+ ~Heartbeat_Application (void);
+
+ // Initializes the object: connects with EC as a supplier and a
+ // consumer and registers with reactor for timeouts. If init ()
+ // completes successfully, shutdown () must be called when this
+ // object is no longer needed, for proper resource cleanup. (This
+ // is normally done by handle_timeout() method, but if handle_timeout()
+ // will not have a chance to execute, it is the responsibility of
+ // the user.)
+ void init (CORBA::ORB_var orb,
+ RtecEventChannelAdmin::EventChannel_var ec
+ ACE_ENV_ARG_DECL);
+
+ // No-op if the object hasn't been fully initialized. Otherwise,
+ // deregister from reactor and poa, destroy ec or just disconnect from it
+ // (based on <destroy_ec> flag), and shut down the orb.
+ void shutdown (void);
+
+ /// Send another heartbeat or, if we already sent/attempted the required
+ /// number of heartbeats, perform shutdown().
+ int handle_timeout (const ACE_Time_Value& tv,
+ const void* act);
+
+ /// PushConsumer methods.
+ //@{
+ /// Update our <heartbeats_> database to reflect newly received heartbeats.
+ virtual void push (const RtecEventComm::EventSet &events
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException));
+
+ /// Initiate shutdown().
+ virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC((CORBA::SystemException));
+ //@}
+
+private:
+
+ /**
+ * @class Timeout_Handler
+ *
+ * @brief Helper class for receiving timeouts from Reactor.
+ */
+ class Timeout_Handler : public ACE_Event_Handler
+ {
+ public:
+ /// Constructor.
+ Timeout_Handler (Heartbeat_Application *recv);
+ /// Reactor callback.
+ virtual int handle_timeout (const ACE_Time_Value& tv,
+ const void* act);
+ private:
+ /// We callback to this object when a message arrives.
+ Heartbeat_Application* receiver_;
+ };
+
+ /// Helpers.
+ //@{
+ /// Verify that arguments are not nil and store their values.
+ int check_args (CORBA::ORB_var orb,
+ RtecEventChannelAdmin::EventChannel_var ec);
+ /// Connects to EC as a supplier.
+ void connect_as_supplier (ACE_ENV_SINGLE_ARG_DECL);
+ /// Connects to EC as a consumer. Activate with default POA.
+ void connect_as_consumer (ACE_ENV_SINGLE_ARG_DECL);
+ /// Call destroy() on the EC. Does not propagate exceptions.
+ void destroy_ec (void);
+ /// Registers with orb's reactor for timeouts ocurring every 0.5
+ /// seconds. Returns 0 on success, -1 on error.
+ int register_for_timeouts (void);
+ /// Deregister from reactor.
+ void stop_timeouts (void);
+ //@}
+
+ /// Flag indicating whether this object has been fully initialized.
+ int initialized_;
+
+ /// Helper object for receiving timeouts from Reactor.
+ Timeout_Handler timeout_handler_;
+
+ /// Number of heartbeats we sent so far.
+ size_t n_timeouts_;
+
+ /// Info we keep on each HEARTBEAT source.
+ typedef struct {
+ pid_t pid;
+ char hostname [MAXHOSTNAMELEN];
+ int total;
+ } HEARTBEAT_SOURCE_ENTRY;
+
+ /// Stores info on all heartbeats we received so far.
+ ACE_Array_Base<HEARTBEAT_SOURCE_ENTRY> heartbeats_;
+
+ /// Our identity: pid followed by hostname. We include this info into each
+ /// heartbeat we send.
+ char hostname_and_pid_ [MAXHOSTNAMELEN+11];
+
+ /// ORB and EC pointers - to allow cleanup down the road.
+ CORBA::ORB_var orb_;
+ RtecEventChannelAdmin::EventChannel_var ec_;
+
+ /// Consumer proxy which represents us in EC as a supplier.
+ RtecEventChannelAdmin::ProxyPushConsumer_var consumer_;
+
+ typedef TAO_EC_Auto_Command<TAO_ECG_UDP_Sender_Disconnect_Command>
+ Supplier_Proxy_Disconnect;
+ typedef TAO_EC_Auto_Command<TAO_ECG_UDP_Receiver_Disconnect_Command>
+ Consumer_Proxy_Disconnect;
+
+ /// Manages our connection to Supplier Proxy.
+ Supplier_Proxy_Disconnect supplier_proxy_disconnect_;
+ /// Manages our connection to Consumer Proxy.
+ Consumer_Proxy_Disconnect consumer_proxy_disconnect_;
+};
+// **************************************************************************
+
+Heartbeat_Application::Timeout_Handler::
+Timeout_Handler (Heartbeat_Application* r)
+ : receiver_ (r)
+{
+}
+
+int
+Heartbeat_Application::Timeout_Handler::
+handle_timeout (const ACE_Time_Value& tv,
+ const void* act)
+{
+ return this->receiver_->handle_timeout (tv, act);
+}
+
+// **************************************************************************
+
+Heartbeat_Application::Heartbeat_Application (void)
+ : initialized_ (0)
+ , timeout_handler_ (this)
+ , n_timeouts_ (0)
+ , orb_ ()
+ , ec_ ()
+ , consumer_ ()
+ , supplier_proxy_disconnect_ ()
+ , consumer_proxy_disconnect_ ()
+{
+}
+
+Heartbeat_Application::~Heartbeat_Application (void)
+{
+}
+
+int
+Heartbeat_Application::check_args (CORBA::ORB_var orb,
+ RtecEventChannelAdmin::EventChannel_var ec)
+{
+ if (CORBA::is_nil (ec.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "%N (%l): Nil ec argument to "
+ "Heartbeat_Application::init\n"),
+ -1);
+ }
+
+ if (CORBA::is_nil (orb.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "%N (%l): Nil orb argument to "
+ "Heartbeat_Application::init\n"),
+ -1);
+ }
+
+ this->ec_ = ec;
+ this->orb_ = orb;
+
+ return 0;
+}
+
+void
+Heartbeat_Application::init (CORBA::ORB_var orb,
+ RtecEventChannelAdmin::EventChannel_var ec
+ ACE_ENV_ARG_DECL)
+{
+ // Verify arguments.
+ if (this->check_args (orb, ec) == -1)
+ {
+ ACE_THROW (CORBA::INTERNAL ());
+ }
+
+ // Get hostname & process id, i.e., identity of this application.
+ pid_t pid = ACE_OS::getpid ();
+ ACE_OS::memcpy (this->hostname_and_pid_,
+ &pid,
+ sizeof (pid));
+
+ if (gethostname (this->hostname_and_pid_ + sizeof (pid),
+ MAXHOSTNAMELEN)
+ != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "Heartbeat_Application::init - "
+ "cannot get hostname\n"));
+ ACE_THROW (CORBA::INTERNAL ());
+ }
+
+ // Connect to EC as a supplier.
+ this->connect_as_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Connect to EC as a consumer.
+ ACE_TRY
+ {
+ this->connect_as_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ this->consumer_proxy_disconnect_.execute ();
+ ACE_RE_THROW;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+
+ // Register for reactor timeouts.
+ if (this->register_for_timeouts () == -1)
+ {
+ this->consumer_proxy_disconnect_.execute ();
+ this->supplier_proxy_disconnect_.execute ();
+ this->deactivator_.deactivate ();
+ ACE_THROW (CORBA::INTERNAL ());
+ }
+
+ this->initialized_ = 1;
+}
+
+int
+Heartbeat_Application::register_for_timeouts (void)
+{
+ // Schedule timeout every 0.5 seconds, for sending heartbeat events.
+ ACE_Time_Value timeout_interval (0, 500000);
+ ACE_Reactor *reactor = this->orb_->orb_core ()->reactor ();
+ if (!reactor
+ || reactor->schedule_timer (&this->timeout_handler_, 0,
+ timeout_interval,
+ timeout_interval) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Heartbeat_Application::register_for_timeouts - "
+ "cannot schedule timer\n"),
+ -1);
+ }
+
+ return 0;
+}
+
+void
+Heartbeat_Application::stop_timeouts (void)
+{
+ ACE_Reactor *reactor = this->orb_->orb_core ()->reactor ();
+ if (!reactor
+ || reactor->cancel_timer (&this->timeout_handler_) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "Heartbeat_Application::stop_timeouts - "
+ "cannot deregister from reactor.\n"));
+ }
+}
+
+void
+Heartbeat_Application::connect_as_supplier (ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Obtain reference to SupplierAdmin.
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ this->ec_->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Obtain ProxyPushConsumer and connect this supplier.
+ RtecEventChannelAdmin::ProxyPushConsumer_var proxy =
+ supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ Consumer_Proxy_Disconnect new_proxy_disconnect (proxy.in ());
+
+ ACE_SupplierQOS_Factory qos;
+ qos.insert (SOURCE_ID, HEARTBEAT, 0, 1);
+
+ proxy->connect_push_supplier (RtecEventComm::PushSupplier::_nil (),
+ qos.get_SupplierQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Update resource managers.
+ this->consumer_ = proxy._retn ();
+ this->consumer_proxy_disconnect_.set_command (new_proxy_disconnect);
+}
+
+void
+Heartbeat_Application::connect_as_consumer (ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Activate with poa.
+ RtecEventComm::PushConsumer_var consumer_ref;
+ PortableServer::POA_var poa = this->_default_POA ();
+
+ TAO_EC_Object_Deactivator deactivator;
+ activate (consumer_ref,
+ poa.in (),
+ this,
+ deactivator
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Obtain reference to ConsumerAdmin.
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ this->ec_->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Obtain ProxyPushSupplier..
+ RtecEventChannelAdmin::ProxyPushSupplier_var proxy =
+ consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ Supplier_Proxy_Disconnect new_proxy_disconnect (proxy.in ());
+
+ // Connect this consumer.
+ ACE_ConsumerQOS_Factory qos;
+ qos.start_disjunction_group (1);
+ qos.insert_type (ACE_ES_EVENT_ANY, 0);
+ proxy->connect_push_consumer (consumer_ref.in (),
+ qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Update resource managers.
+ this->supplier_proxy_disconnect_.set_command (new_proxy_disconnect);
+ this->set_deactivator (deactivator);
+}
+
+int
+Heartbeat_Application::handle_timeout (const ACE_Time_Value&,
+ const void*)
+{
+ ACE_TRY_NEW_ENV
+ {
+ if (this->n_timeouts_++ < HEARTBEATS_TO_SEND)
+ {
+ RtecEventComm::EventSet events (1);
+ events.length (1);
+ // Events travelling through gateways must have a ttl count of at
+ // least 1!
+ events[0].header.ttl = 1;
+ events[0].header.type = HEARTBEAT;
+ events[0].header.source = SOURCE_ID;
+
+ // Store our hostname and process id in the data portion of
+ // the event.
+ events[0].data.payload.replace (MAXHOSTNAMELEN+11,
+ MAXHOSTNAMELEN+11,
+ (u_char *)this->hostname_and_pid_,
+ 0);
+
+ this->consumer_->push (events ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ else
+ // We already sent the required number of heartbeats. Time to
+ // shutdown this app.
+ {
+ this->shutdown ();
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Suppressed the following exception in "
+ "Heartbeat_Application::handle_timeout:\n");
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+void
+Heartbeat_Application::push (const RtecEventComm::EventSet &events
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ for (CORBA::ULong i = 0; i < events.length (); ++i)
+ {
+ // Figure out heartbeat source.
+ const u_char * buffer = events[i].data.payload.get_buffer ();
+ pid_t pid = *((pid_t*) buffer);
+ char * host = (char*) buffer + sizeof (pid);
+
+ // Update heartbeat database.
+ int found = 0;
+ size_t size = this->heartbeats_.size ();
+ for (size_t j = 0; j < size; ++j)
+ {
+ if (this->heartbeats_[j].pid == pid
+ && ACE_OS::strcmp (this->heartbeats_[j].hostname, host)
+ == 0)
+ {
+ this->heartbeats_[j].total++;
+ found = 1;
+ break;
+ }
+ }
+ // Make new entry in the database.
+ if (!found)
+ {
+ if (this->heartbeats_.size (size + 1)
+ == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "Unable to add new entry "
+ "to heartbeat database \n"));
+ break;
+ }
+
+ this->heartbeats_[size].pid = pid;
+ this->heartbeats_[size].total = 1;
+ ACE_OS::memcpy (this->heartbeats_[size].hostname,
+ host,
+ ACE_OS::strlen (host) + 1);
+ }
+ }
+}
+
+void
+Heartbeat_Application::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC((CORBA::SystemException))
+{
+ this->shutdown ();
+}
+
+void
+Heartbeat_Application::destroy_ec (void)
+{
+ if (!CORBA::is_nil (this->ec_.in ()))
+ {
+ ACE_TRY_NEW_ENV
+ {
+ this->ec_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Suppressed the following exception in "
+ "Application_Heartbeat::destroy_ec\n");
+ }
+ ACE_ENDTRY;
+
+ this->ec_ = RtecEventChannelAdmin::EventChannel::_nil ();
+ }
+}
+void
+Heartbeat_Application::shutdown (void)
+{
+ if (!this->initialized_)
+ return;
+
+ this->initialized_ = 0;
+
+ // Deregister from Reactor.
+ this->stop_timeouts ();
+
+ // Disconnect from ECs as a consumer.
+ this->supplier_proxy_disconnect_.execute ();
+ // Disconnect from EC as a supplier.
+ this->consumer_proxy_disconnect_.execute ();
+
+ if (destroy_ec_flag)
+ {
+ this->destroy_ec ();
+ }
+
+ // Deregister from POA.
+ this->deactivator_.deactivate ();
+
+ // Print out heartbeats report.
+ pid_t pid = ACE_OS::getpid ();
+ char hostname[MAXHOSTNAMELEN + 1];
+ if (gethostname (hostname, MAXHOSTNAMELEN) != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "Heartbeat_Application::shutdown - "
+ "cannot get hostname\n"));
+ hostname[0] = '\0';
+ }
+ ACE_DEBUG ((LM_DEBUG,
+ "%d@%s Received following heartbeats:\n",
+ pid, hostname));
+ for (size_t i = 0; i < this->heartbeats_.size (); ++i)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "Host %s, pid %d - total of %u\n",
+ this->heartbeats_[i].hostname,
+ this->heartbeats_[i].pid,
+ this->heartbeats_[i].total));
+ }
+
+ // Shutdown the ORB.
+ ACE_TRY_NEW_ENV
+ {
+ this->orb_->shutdown (0 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "The following exception occured in "
+ "Heartbeat_Application::shutdown:\n");
+ }
+ ACE_ENDTRY;
+}
+
+////////////////////////////////////////////////////////////
+int
+check_for_nil (CORBA::Object_ptr obj, const char *message)
+{
+ if (CORBA::is_nil (obj))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ERROR: Object reference <%s> is nil\n",
+ message),
+ -1);
+ else
+ return 0;
+}
+
+int
+parse_args (int argc, char ** argv)
+{
+ ACE_Get_Opt get_opt (argc, argv, "d");
+ int opt;
+
+ while ((opt = get_opt ()) != EOF)
+ {
+ switch (opt)
+ {
+ case 'd':
+ destroy_ec_flag = 1;
+ break;
+
+ case '?':
+ default:
+ ACE_DEBUG ((LM_DEBUG,
+ "Usage: %s "
+ "-d"
+ "\n",
+ argv[0]));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ // We may want this to be alive beyond the next block.
+ TAO_EC_Servant_Var<Heartbeat_Application> app;
+
+ ACE_TRY_NEW_ENV
+ {
+ // Initialize ORB and POA, POA Manager, parse args.
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (parse_args (argc, argv) == -1)
+ return 1;
+
+ CORBA::Object_var obj =
+ orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ PortableServer::POA_var poa =
+ PortableServer::POA::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ if (check_for_nil (poa.in (), "POA") == -1)
+ return 1;
+
+ PortableServer::POAManager_var manager =
+ poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Obtain reference to EC.
+ obj = orb->resolve_initial_references ("Event_Service" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ RtecEventChannelAdmin::EventChannel_var ec =
+ RtecEventChannelAdmin::EventChannel::_narrow (obj.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ if (check_for_nil (ec.in (), "EC") == -1)
+ return 1;
+
+ // Init our application.
+ app = new Heartbeat_Application;
+ if (!app.in ())
+ return 1;
+
+ app->init (orb, ec ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Allow processing of CORBA requests.
+ manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Receive events from EC.
+ orb->run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
+ "Exception in Heartbeat Application:");
+ // Since there was an exception, application might not have had
+ // a chance to shutdown.
+ app->shutdown ();
+ return 1;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Two_Way/gateway-ec.cpp b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/gateway-ec.cpp
new file mode 100644
index 00000000000..c048843d90b
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/gateway-ec.cpp
@@ -0,0 +1,14 @@
+// $Id$
+
+#include "Gateway_EC.h"
+
+int
+main (int argc, char ** argv)
+{
+ Gateway_EC test;
+
+ if (test.run (argc, argv) == -1)
+ return 1;
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Two_Way/gateway.conf b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/gateway.conf
new file mode 100644
index 00000000000..e87f9196f76
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/gateway.conf
@@ -0,0 +1,3 @@
+# $Id$
+static EC_Factory "-ECfiltering basic -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"
+static ECG_Mcast_Gateway "-ECGService two_way -ECGAddressServerArg 230.100.1.7:26700"
diff --git a/TAO/orbsvcs/tests/Event/Mcast/Two_Way/run_test.pl b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/run_test.pl
new file mode 100755
index 00000000000..ffbeb68a9d6
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Mcast/Two_Way/run_test.pl
@@ -0,0 +1,205 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+# This is a Perl script that runs Simple EC Mcast example. It starts
+# consumer, supplier and two (federated) Event Channel servers.
+# See README for more details.
+
+use lib '../../../../../../bin';
+use PerlACE::Run_Test;
+use POSIX;
+
+###############################################################
+# Configuration parameters
+###############################################################
+
+# Amount of delay (in seconds) between starting a server and a client
+# to allow proper server initialization.
+$sleeptime = 10;
+# Number of Event Channel/Application pairs that will be started up.
+$number_of_applications = 3;
+
+# Variables for command-line arguments to client and server
+# executables.
+$iorfile_base = "ec.ior";
+$conffile = PerlACE::LocalFile ("gateway.conf");
+
+#################################################################
+# Subs
+#################################################################
+
+sub run_test
+{
+ # Start federated Event Channels.
+ for ($i = 0; $i < $number_of_applications; $i++)
+ {
+ if (run_ec ($i, $conffile, $iorfile_base.$i) != 0) {
+ kill_processes (); return -1;
+ }
+ }
+
+ # Start EC clients.
+ for ($i = 0; $i < $number_of_applications; $i++)
+ {
+ my $ps_index = $number_of_applications + $i;
+ my $args = "-d -ORBInitRef Event_Service=file://$iorfile_base$i";
+ $ps[$ps_index] =
+ new PerlACE::Process ("application", $args);
+ if ($ps[$ps_index]->Spawn () == -1) {
+ kill_processes (); return -1;
+ }
+ }
+
+ # Shutdown.
+ return kill_processes ();
+}
+
+# Start Event Channel server.
+sub run_ec
+{
+ my $ec_id = $_[0];
+ my $conf_file = $_[1];
+ my $ior_file = $_[2];
+
+ unlink $ior_file;
+
+ $ps[$ec_id] = new PerlACE::Process ("gateway-ec",
+ "-ORBsvcconf $conf_file -i $ior_file");
+ if ($ps[$ec_id]->Spawn () == -1) {
+ return 1;
+ }
+
+ if (PerlACE::waitforfile_timed ($ior_file, $sleeptime) == -1)
+ {
+ print STDERR "ERROR: cannot find IOR file <$ior_file>\n";
+ $ps[$ec_id]->Kill ();
+ return 1;
+ }
+
+ return 0;
+}
+
+# Wait for and kill, if necessary, all started processes.
+sub kill_processes
+{
+ my $result = 0;
+
+ foreach $p (@ps)
+ {
+ if ($p->WaitKill (60) != 0) {
+ $result = -1;
+ }
+ }
+
+ if ($result == -1) {
+ print STDERR "ERROR detected\n";
+ return -1;
+ }
+
+ return 0;
+}
+
+sub restore_output
+{
+ # Restore output facilities.
+ close (STDERR);
+ close (STDOUT);
+ open (STDOUT, ">&OLDOUT");
+ open (STDERR, ">&OLDERR");
+}
+
+sub redirect_output
+{
+ my $rundate = POSIX::strftime("%Y_%m_%d_%H_%M", localtime);
+ $output_file = PerlACE::LocalFile ("run_test_$rundate");
+
+ open (OLDOUT, ">&STDOUT");
+ open (STDOUT, ">$output_file") or die "can't redirect stdout: $!";
+ open (OLDERR, ">&STDERR");
+ open (STDERR, ">&STDOUT") or die "can't redirect stderror: $!";
+}
+
+sub analyze_results
+{
+ if (! open (TEST_OUTPUT, "<$output_file"))
+ {
+ print STDERR "ERROR: Could not open $output_file\n";
+ return -1;
+ }
+
+ my $status = 0;
+ while (<TEST_OUTPUT>)
+ {
+ if (m/total of/)
+ {
+ chomp $_;
+ my @words = split (/ /, $_);
+ my $pid = $words[3];
+ my $h = $words[7];
+ $heartbeats{$pid} += $h;
+ }
+ elsif (m/Received following heartbeats/)
+ {
+ #skip this line - we do our own counting.
+ }
+ else
+ {
+ $status = -1;
+ print STDERR $_;
+ }
+ }
+ close (TEST_OUTPUT);
+
+ foreach $pid (keys %heartbeats)
+ {
+ my $ideal_heartbeats = $number_of_applications * 50;
+ my $received_heartbeats = $heartbeats{$pid};
+ my $in_range = (($ideal_heartbeats - $received_heartbeats)
+ <= $number_of_applications);
+ my $range_note = " (";
+ if (! $in_range) {
+ $range_note .= "NOT ";
+ $status = -1;
+ }
+ $range_note.=
+ "within range of $number_of_applications from $ideal_heartbeats)";
+ print STDERR
+ "Received $received_heartbeats "
+ ."heartbeats from pid $pid";
+ print STDERR "$range_note\n";
+ }
+
+ if ($status == 0) {
+ print STDERR "SUCCESS\n";
+ return 0;
+ }
+
+ print STDERR "ERROR - check $output_file for full output.\n";
+ return -1;
+}
+
+##############################################################
+# Run executables.
+##############################################################
+
+
+$status = 0;
+
+redirect_output ();
+
+if (run_test () == -1) {
+ $status = 1;
+}
+
+restore_output ();
+
+if (analyze_results () == -1) {
+ $status = 1;
+}
+
+exit $status;
+
diff --git a/TAO/orbsvcs/tests/Event/Performance/Connect.cpp b/TAO/orbsvcs/tests/Event/Performance/Connect.cpp
new file mode 100644
index 00000000000..874f96cc737
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/Connect.cpp
@@ -0,0 +1,400 @@
+// $Id$
+
+#include "Connect.h"
+#include "Consumer.h"
+#include "Supplier.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "ace/Arg_Shifter.h"
+#include "ace/High_Res_Timer.h"
+#include "ace/OS_NS_strings.h"
+
+ACE_RCSID (EC_Tests_Performance,
+ Connect,
+ "$Id$")
+
+int
+main (int argc, char *argv [])
+{
+ EC_Connect driver;
+ return driver.run (argc, argv);
+}
+
+// ****************************************************************
+
+EC_Connect::EC_Connect (void)
+ : order_ (0)
+{
+}
+
+void
+EC_Connect::execute_test (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+{
+ // this->EC_Driver::execute_test (ACE_ENV_SINGLE_ARG_PARAMETER);
+}
+
+int
+EC_Connect::parse_args (int& argc, char* argv[])
+{
+ if (this->EC_Driver::parse_args (argc, argv) != 0)
+ return -1;
+
+ ACE_Arg_Shifter arg_shifter (argc, argv);
+
+ while (arg_shifter.is_anything_left ())
+ {
+ const char *arg = arg_shifter.get_current ();
+
+ if (ACE_OS::strcmp (arg, "-connection_order") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ const char* opt = arg_shifter.get_current ();
+ if (ACE_OS::strcasecmp (opt, "consumers") == 0)
+ this->order_ = 0;
+ else if (ACE_OS::strcasecmp (opt, "suppliers") == 0)
+ this->order_ = 1;
+ else if (ACE_OS::strcasecmp (opt, "interleaved") == 0)
+ this->order_ = 2;
+ else
+ ACE_ERROR ((LM_ERROR,
+ "EC_Connect - invalid choice <%s> for"
+ " connection order\n",
+ opt));
+
+ arg_shifter.consume_arg ();
+ }
+ }
+
+ else
+ {
+ arg_shifter.ignore_arg ();
+ }
+ }
+ return 0;
+}
+
+void
+EC_Connect::print_usage (void)
+{
+ this->EC_Driver::print_usage ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ "EC_Connect Usage:\n"
+ " -connection_order [consumers|suppliers|interleaved]\n"
+ ));
+}
+
+void
+EC_Connect::print_args (void) const
+{
+ this->EC_Driver::print_args ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ "EC_Connect parameters:\n"
+ " order = <%d>\n",
+ this->order_));
+}
+
+void
+EC_Connect::dump_results (void)
+{
+ ACE_UINT32 gsf = ACE_High_Res_Timer::global_scale_factor ();
+ ACE_DEBUG ((LM_DEBUG, "\nConnect time:\n"));
+ this->consumer_connect_.dump_results ("Consumer/connect", gsf);
+ this->supplier_connect_.dump_results ("Supplier/connect", gsf);
+
+ ACE_DEBUG ((LM_DEBUG, "\nDisconnect time:\n"));
+}
+
+void
+EC_Connect::connect_consumer (
+ RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin,
+ int i
+ ACE_ENV_ARG_DECL)
+{
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+ this->EC_Driver::connect_consumer (consumer_admin,
+ i
+ ACE_ENV_ARG_PARAMETER);
+ ACE_hrtime_t now = ACE_OS::gethrtime ();
+ this->consumer_connect_.sample (now - this->start_time_,
+ now - start);
+}
+
+void
+EC_Connect::connect_supplier (
+ RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin,
+ int i
+ ACE_ENV_ARG_DECL)
+{
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+ this->EC_Driver::connect_supplier (supplier_admin,
+ i
+ ACE_ENV_ARG_PARAMETER);
+ ACE_hrtime_t now = ACE_OS::gethrtime ();
+ this->supplier_connect_.sample (now - this->start_time_,
+ now - start);
+}
+
+EC_Consumer*
+EC_Connect::allocate_consumer (int i)
+{
+ return new ECC_Consumer (this, this->consumers_ + i);
+}
+
+EC_Supplier*
+EC_Connect::allocate_supplier (int i)
+{
+ return new ECC_Supplier (this, this->consumers_ + i);
+}
+
+void
+EC_Connect::connect_clients (ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->start_time_ = ACE_OS::gethrtime ();
+ switch (this->order_)
+ {
+ default:
+ case 0:
+ this->connect_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ this->connect_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ return;
+
+ case 1:
+ this->connect_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ this->connect_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ return;
+
+ case 2:
+ break;
+ }
+
+ int max = this->n_consumers_;
+ if (max < this->n_suppliers_)
+ max = this->n_suppliers_;
+
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ this->event_channel_->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ this->event_channel_->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ for (int i = 0; i != max; ++i)
+ {
+ if (i < this->n_consumers_)
+ {
+ this->connect_consumer (consumer_admin.in (), i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ if (i < this->n_suppliers_)
+ {
+ this->connect_supplier (supplier_admin.in (), i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ }
+
+}
+
+void
+EC_Connect::disconnect_clients (ACE_ENV_SINGLE_ARG_DECL)
+{
+ switch (this->order_)
+ {
+ default:
+ case 0:
+ this->disconnect_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ this->disconnect_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ return;
+
+ case 1:
+ this->disconnect_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ this->disconnect_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ return;
+
+ case 2:
+ break;
+ }
+
+ int max = this->n_consumers_;
+ if (max < this->n_suppliers_)
+ max = this->n_suppliers_;
+
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ this->event_channel_->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ this->event_channel_->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ ACE_hrtime_t start_time = ACE_OS::gethrtime ();
+ for (int i = 0; i != max; ++i)
+ {
+ if (i < this->n_suppliers_)
+ {
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+
+ this->suppliers_[i]->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ ACE_hrtime_t now = ACE_OS::gethrtime ();
+ this->supplier_disconnect_.sample (now - start_time,
+ now - start);
+ }
+ if (i < this->n_consumers_)
+ {
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+
+ this->consumers_[i]->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ ACE_hrtime_t now = ACE_OS::gethrtime ();
+ this->consumer_disconnect_.sample (now - start_time,
+ now - start);
+ }
+ }
+ ACE_UINT32 gsf = ACE_High_Res_Timer::global_scale_factor ();
+ this->consumer_disconnect_.dump_results ("Consumer/disconnect", gsf);
+ this->supplier_disconnect_.dump_results ("Supplier/disconnect", gsf);
+}
+
+void
+EC_Connect::disconnect_consumers (ACE_ENV_SINGLE_ARG_DECL)
+{
+ ACE_hrtime_t start_time = ACE_OS::gethrtime ();
+ for (int i = 0; i < this->n_consumers_; ++i)
+ {
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+
+ this->consumers_[i]->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ ACE_hrtime_t now = ACE_OS::gethrtime ();
+ this->consumer_disconnect_.sample (now - start_time,
+ now - start);
+ }
+ ACE_UINT32 gsf = ACE_High_Res_Timer::global_scale_factor ();
+ this->consumer_disconnect_.dump_results ("Consumer/disconnect",
+ gsf);
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Connect (%P|%t) consumers disconnected\n"));
+}
+
+void
+EC_Connect::disconnect_suppliers (ACE_ENV_SINGLE_ARG_DECL)
+{
+ ACE_hrtime_t start_time = ACE_OS::gethrtime ();
+ for (int i = 0; i < this->n_suppliers_; ++i)
+ {
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+
+ this->suppliers_[i]->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ ACE_hrtime_t now = ACE_OS::gethrtime ();
+ this->supplier_disconnect_.sample (now - start_time,
+ now - start);
+ }
+ ACE_UINT32 gsf = ACE_High_Res_Timer::global_scale_factor ();
+ this->supplier_disconnect_.dump_results ("Supplier/disconnect",
+ gsf);
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Connect (%P|%t) suppliers disconnected\n"));
+}
+
+
+// ****************************************************************
+
+ECC_Consumer::ECC_Consumer (EC_Driver* driver, void* cookie)
+ : EC_Consumer (driver, cookie)
+{
+}
+
+void
+ECC_Consumer::connect (
+ RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin,
+ const RtecEventChannelAdmin::ConsumerQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL)
+{
+ this->EC_Consumer::connect (consumer_admin,
+ qos,
+ shutdown_event_type
+ ACE_ENV_ARG_PARAMETER);
+}
+
+void
+ECC_Consumer::connect (
+ const RtecEventChannelAdmin::ConsumerQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL)
+{
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+ this->EC_Consumer::connect (qos,
+ shutdown_event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_hrtime_t now = ACE_OS::gethrtime ();
+ this->connect_time_.sample (now, now - start);
+}
+
+void
+ECC_Consumer::dump_results (const char* name,
+ ACE_UINT32 gsf)
+{
+ this->connect_time_.dump_results (name, gsf);
+ this->EC_Consumer::dump_results (name, gsf);
+}
+
+// ****************************************************************
+
+ECC_Supplier::ECC_Supplier (EC_Driver* driver, void* cookie)
+ : EC_Supplier (driver, cookie)
+{
+}
+
+void
+ECC_Supplier::connect (
+ RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin,
+ const RtecEventChannelAdmin::SupplierQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL)
+{
+ this->EC_Supplier::connect (supplier_admin,
+ qos,
+ shutdown_event_type
+ ACE_ENV_ARG_PARAMETER);
+}
+
+void
+ECC_Supplier::connect (
+ const RtecEventChannelAdmin::SupplierQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL)
+{
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+ this->EC_Supplier::connect (qos,
+ shutdown_event_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_hrtime_t now = ACE_OS::gethrtime ();
+ this->connect_time_.sample (now, now - start);
+}
+
+void
+ECC_Supplier::dump_results (const char* name,
+ ACE_UINT32 gsf)
+{
+ this->connect_time_.dump_results (name, gsf);
+ this->EC_Supplier::dump_results (name, gsf);
+}
diff --git a/TAO/orbsvcs/tests/Event/Performance/Connect.h b/TAO/orbsvcs/tests/Event/Performance/Connect.h
new file mode 100644
index 00000000000..caaf08b425a
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/Connect.h
@@ -0,0 +1,133 @@
+/* -*- C++ -*- */
+// $Id$
+//
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS Real-time Event Channel testsuite
+//
+// = FILENAME
+// Connect
+//
+// = AUTHOR
+// Carlos O'Ryan (coryan@cs.wustl.edu)
+//
+// ============================================================================
+
+#ifndef EC_CONNECT_H
+#define EC_CONNECT_H
+
+#include "Consumer.h"
+#include "Supplier.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class EC_Connect : public EC_Driver
+{
+ //
+ // = TITLE
+ // Test the EC connection feature
+ //
+ // = DESCRIPTION
+ // The EC can be configured to allow re-connection of suppliers
+ // and consumers, this test verifies that:
+ // + The EC does *not* allow connections if the feature is
+ // disabled (the default)
+ // + The EC does allow connections if the feature is enabled
+ // and:
+ // - There are no memory leaks
+ // - Compares the time required for a connection vs a complete
+ // connect/disconnect cycle, specially as the number of
+ // suppliers and consumers increases.
+ //
+public:
+ EC_Connect (void);
+ // Constructor
+
+ // = The EC_Driver methods
+ virtual int parse_args (int& argc, char* argv[]);
+ virtual void print_usage (void);
+ virtual void print_args (void) const;
+
+ void execute_test (ACE_ENV_SINGLE_ARG_DECL);
+ // Don't run the suppliers, just test connect and disconnect calls.
+
+ virtual void dump_results (void);
+
+ virtual void connect_consumer (
+ RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin,
+ int i
+ ACE_ENV_ARG_DECL);
+ virtual void connect_supplier (
+ RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin,
+ int i
+ ACE_ENV_ARG_DECL);
+ virtual void disconnect_consumers (ACE_ENV_SINGLE_ARG_DECL);
+ virtual void disconnect_suppliers (ACE_ENV_SINGLE_ARG_DECL);
+
+ virtual EC_Consumer* allocate_consumer (int i);
+ virtual EC_Supplier* allocate_supplier (int i);
+
+ virtual void connect_clients (ACE_ENV_SINGLE_ARG_DECL_NOT_USED);
+ virtual void disconnect_clients (ACE_ENV_SINGLE_ARG_DECL_NOT_USED);
+
+private:
+ ACE_hrtime_t start_time_;
+ ACE_Throughput_Stats consumer_connect_;
+ ACE_Throughput_Stats supplier_connect_;
+ ACE_Throughput_Stats consumer_disconnect_;
+ ACE_Throughput_Stats supplier_disconnect_;
+
+ int order_;
+ // What is connected first?
+};
+
+// ****************************************************************
+
+class ECC_Consumer : public EC_Consumer
+{
+public:
+ ECC_Consumer (EC_Driver *driver, void* cookie);
+
+ virtual void connect (
+ RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin,
+ const RtecEventChannelAdmin::ConsumerQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL);
+ virtual void connect (
+ const RtecEventChannelAdmin::ConsumerQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL);
+ virtual void dump_results (const char* name,
+ ACE_UINT32 global_scale_factor);
+
+private:
+ ACE_Throughput_Stats connect_time_;
+};
+
+// ****************************************************************
+
+class ECC_Supplier : public EC_Supplier
+{
+public:
+ ECC_Supplier (EC_Driver *driver, void* cookie);
+
+ virtual void connect (
+ RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin,
+ const RtecEventChannelAdmin::SupplierQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL);
+ virtual void connect (
+ const RtecEventChannelAdmin::SupplierQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL);
+ virtual void dump_results (const char* name,
+ ACE_UINT32 global_scale_factor);
+
+private:
+ ACE_Throughput_Stats connect_time_;
+};
+
+#endif /* EC_CONNECT_H */
diff --git a/TAO/orbsvcs/tests/Event/Performance/Event_Performance.mpc b/TAO/orbsvcs/tests/Event/Performance/Event_Performance.mpc
new file mode 100644
index 00000000000..b0df7a26f09
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/Event_Performance.mpc
@@ -0,0 +1,38 @@
+// -*- MPC -*-
+// $Id$
+
+project(*Throughput): eventperftestexe {
+ exename = Throughput
+ Source_Files {
+ Throughput.cpp
+ }
+}
+
+project(*Connect): eventperftestexe {
+ exename = Connect
+ Source_Files {
+ Connect.cpp
+ }
+}
+
+project(*Inversion): eventperftestexe {
+ exename = Inversion
+ Source_Files {
+ Inversion.cpp
+ }
+}
+
+project(*Latency): eventperftestexe, strategies {
+ exename = Latency
+ Source_Files {
+ Latency.cpp
+ }
+}
+
+project(*Latency_Server): eventperftestexe, rtevent_serv, strategies {
+ exename = Latency_Server
+ Source_Files {
+ Latency_Server.cpp
+ }
+}
+
diff --git a/TAO/orbsvcs/tests/Event/Performance/Inversion.cpp b/TAO/orbsvcs/tests/Event/Performance/Inversion.cpp
new file mode 100644
index 00000000000..c3c4661d8c2
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/Inversion.cpp
@@ -0,0 +1,176 @@
+// $Id$
+
+#include "Inversion.h"
+#include "Consumer.h"
+#include "Supplier.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "ace/Sched_Params.h"
+#include "ace/Arg_Shifter.h"
+
+ACE_RCSID (EC_Tests_Performance,
+ Inversion,
+ "$Id$")
+
+int
+main (int argc, char *argv [])
+{
+ EC_Inversion driver;
+ return driver.run (argc, argv);
+}
+
+// ****************************************************************
+
+EC_Inversion::EC_Inversion (void)
+ : same_events_ (0)
+{
+}
+
+int
+EC_Inversion::parse_args (int &argc, char *argv [])
+{
+ ACE_Arg_Shifter arg_shifter (argc, argv);
+
+ while (arg_shifter.is_anything_left ())
+ {
+ const char *arg = arg_shifter.get_current ();
+
+ if (ACE_OS::strcmp (arg, "-same_events") == 0)
+ {
+ arg_shifter.consume_arg ();
+ this->same_events_ = 1;
+ }
+
+ else
+ {
+ arg_shifter.ignore_arg ();
+ }
+ }
+
+ int r = this->EC_Driver::parse_args (argc, argv);
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG,
+ "EC_Inversion (%P|%t) "
+ "adjusting number of consumers (2)\n"));
+ return r;
+}
+
+void
+EC_Inversion::connect_consumers (ACE_ENV_SINGLE_ARG_DECL)
+{
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ this->event_channel_->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ ACE_ConsumerQOS_Factory qos0;
+ qos0.start_disjunction_group (2);
+ qos0.insert_type (ACE_ES_EVENT_UNDEFINED, 0);
+ qos0.insert_type (ACE_ES_EVENT_UNDEFINED + 1, 0);
+
+ this->consumers_[0]->connect (consumer_admin.in (),
+ qos0.get_ConsumerQOS (),
+ ACE_ES_EVENT_UNDEFINED + 1
+ ACE_ENV_ARG_PARAMETER);
+
+ for (int i = 1; i < this->n_consumers_; ++i)
+ {
+ int base_event = ACE_ES_EVENT_UNDEFINED + 2;
+ if (this->same_events_)
+ base_event = ACE_ES_EVENT_UNDEFINED;
+
+ ACE_ConsumerQOS_Factory qos1;
+ qos1.start_disjunction_group (2);
+ qos1.insert_type (base_event , 0);
+ qos1.insert_type (base_event + 1, 0);
+
+ this->consumers_[i]->connect (consumer_admin.in (),
+ qos1.get_ConsumerQOS (),
+ base_event + 1
+ ACE_ENV_ARG_PARAMETER);
+ }
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Inversion (%P|%t) connected consumer(s)\n"));
+}
+
+void
+EC_Inversion::connect_suppliers (ACE_ENV_SINGLE_ARG_DECL)
+{
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ this->event_channel_->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ ACE_SupplierQOS_Factory qos0;
+ qos0.insert (1, ACE_ES_EVENT_UNDEFINED, 0, 1);
+ qos0.insert (1, ACE_ES_EVENT_UNDEFINED + 1, 0, 1);
+
+ this->suppliers_[0]->connect (supplier_admin.in (),
+ qos0.get_SupplierQOS (),
+ ACE_ES_EVENT_UNDEFINED + 1
+ ACE_ENV_ARG_PARAMETER);
+
+ for (int j = 1; j != this->n_suppliers_; ++j)
+ {
+ int base_event = ACE_ES_EVENT_UNDEFINED + 2;
+ if (this->same_events_)
+ base_event = ACE_ES_EVENT_UNDEFINED;
+
+ ACE_SupplierQOS_Factory qos1;
+ qos1.insert (1, base_event , 0, 1);
+ qos1.insert (1, base_event + 1, 0, 1);
+
+ this->suppliers_[j]->connect (supplier_admin.in (),
+ qos1.get_SupplierQOS (),
+ base_event + 1
+ ACE_ENV_ARG_PARAMETER);
+ }
+
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Inversion (%P|%t) connected supplier(s)\n"));
+}
+
+void
+EC_Inversion::activate_tasks (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+{
+ int priority;
+
+ if (ACE_BIT_ENABLED (this->thr_create_flags_, THR_SCHED_FIFO))
+ {
+ priority =
+ ACE_Sched_Params::priority_max (ACE_SCHED_FIFO);
+ }
+ else
+ {
+ priority =
+ ACE_Sched_Params::priority_min (ACE_SCHED_OTHER);
+ }
+ if (this->tasks_[0]->activate (this->thr_create_flags_,
+ 1, 0, priority) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "EC_Inversion (%P|%t) cannot activate high prio task\n"));
+ }
+
+ if (ACE_BIT_ENABLED (this->thr_create_flags_, THR_SCHED_FIFO))
+ {
+ priority =
+ (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO)
+ + ACE_Sched_Params::priority_max (ACE_SCHED_FIFO)) / 2;
+ }
+ else
+ {
+ priority =
+ ACE_Sched_Params::priority_min (ACE_SCHED_OTHER);
+ }
+
+ for (int i = 1; i < this->n_suppliers_; ++i)
+ {
+ if (this->tasks_[i]->activate (this->thr_create_flags_,
+ 1, 0, priority) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "EC_Inversion (%P|%t) Cannot activate thread "
+ "for supplier %d\n%p\n",
+ i, "EC_Inversion - OS error is:"));
+ }
+ }
+}
diff --git a/TAO/orbsvcs/tests/Event/Performance/Inversion.h b/TAO/orbsvcs/tests/Event/Performance/Inversion.h
new file mode 100644
index 00000000000..6811eb6c794
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/Inversion.h
@@ -0,0 +1,60 @@
+/* -*- C++ -*- */
+// $Id$
+//
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS Real-time Event Channel testsuite
+//
+// = FILENAME
+// Inversion
+//
+// = AUTHOR
+// Carlos O'Ryan (coryan@cs.wustl.edu)
+//
+// ============================================================================
+
+#ifndef EC_INVERSION_H
+#define EC_INVERSION_H
+
+#include "Driver.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class EC_Inversion : public EC_Driver
+{
+ //
+ // = TITLE
+ // Measure priority inversions in the EC.
+ //
+ // = DESCRIPTION
+ //
+public:
+ EC_Inversion (void);
+ // Constructor
+
+ // = The EC_Driver methods
+ int parse_args (int &argc, char *argv[]);
+ // Parse the arguments, but override the number of consumers.
+ // The options controlling the event types are ignored, and only two
+ // consumers are created.
+
+ virtual void connect_consumers (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS);
+ virtual void connect_suppliers (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS);
+ // In this test there are two consumers, the high priority consumer
+ // receives only events from a single high priority supplier. The
+ // other consumer receives events from a set of low priority
+ // suppliers.
+
+ virtual void activate_tasks (ACE_ENV_SINGLE_ARG_DECL_NOT_USED);
+ // Activate the suppliers at different priorities
+
+private:
+ int same_events_;
+ // If set then both low priority and high priority suppliers
+ // generate the same events.
+};
+
+#endif /* EC_INVERSION_H */
diff --git a/TAO/orbsvcs/tests/Event/Performance/Latency.cpp b/TAO/orbsvcs/tests/Event/Performance/Latency.cpp
new file mode 100644
index 00000000000..2d0cd3903aa
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/Latency.cpp
@@ -0,0 +1,421 @@
+// $Id$
+
+#include "Latency.h"
+#include "orbsvcs/Event_Service_Constants.h"
+
+#include "tao/Messaging/Messaging.h"
+#include "tao/Strategies/advanced_resource.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "ace/High_Res_Timer.h"
+#include "ace/Get_Opt.h"
+#include "ace/Sample_History.h"
+#include "ace/Basic_Stats.h"
+#include "ace/Sched_Params.h"
+#include "ace/OS_NS_errno.h"
+
+ACE_RCSID(EC_Tests_Performance, Latency, "$Id$")
+
+int iterations = 1000;
+int do_dump_history = 0;
+const char *ec_ior = "file://ec.ior";
+
+/// Parse the arguments.
+static int parse_args (int argc, char *argv[]);
+
+int
+main (int argc, char *argv [])
+{
+ int priority =
+ (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO)
+ + ACE_Sched_Params::priority_max (ACE_SCHED_FIFO)) / 2;
+ priority = ACE_Sched_Params::next_priority (ACE_SCHED_FIFO,
+ priority);
+ // Enable FIFO scheduling, e.g., RT scheduling class on Solaris.
+
+ if (ACE_OS::sched_params (ACE_Sched_Params (ACE_SCHED_FIFO,
+ priority,
+ ACE_SCOPE_PROCESS)) != 0)
+ {
+ if (ACE_OS::last_error () == EPERM)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "server (%P|%t): user is not superuser, "
+ "test runs in time-shared class\n"));
+ }
+ else
+ ACE_ERROR ((LM_ERROR,
+ "server (%P|%t): sched_params failed\n"));
+ }
+
+ ACE_TRY_NEW_ENV
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+#if (TAO_HAS_CORBA_MESSAGING == 1)
+ CORBA::Object_var manager_object =
+ orb->resolve_initial_references ("ORBPolicyManager"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::PolicyManager_var policy_manager =
+ CORBA::PolicyManager::_narrow (manager_object.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::Any sync_scope;
+ sync_scope <<= Messaging::SYNC_WITH_TARGET;
+
+ CORBA::PolicyList policy_list (1);
+ policy_list.length (1);
+ policy_list[0] =
+ orb->create_policy (Messaging::SYNC_SCOPE_POLICY_TYPE,
+ sync_scope
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ policy_manager->set_policy_overrides (policy_list,
+ CORBA::SET_OVERRIDE
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+#else
+ ACE_DEBUG ((LM_DEBUG,
+ "CORBA Messaging disabled in this configuration,"
+ " test may not be optimally configured\n"));
+#endif /* TAO_HAS_MESSAGING */
+
+ CORBA::Object_var poa_object =
+ orb->resolve_initial_references("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (poa_object.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ " (%P|%t) Unable to initialize the POA.\n"),
+ 1);
+
+ PortableServer::POA_var root_poa =
+ PortableServer::POA::_narrow (poa_object.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ PortableServer::POAManager_var poa_manager =
+ root_poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ // Get the event channel object reference
+ CORBA::Object_var object =
+ orb->string_to_object (ec_ior ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::EventChannel_var ec =
+ RtecEventChannelAdmin::EventChannel::_narrow (object.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ if (CORBA::is_nil (ec.in ()))
+ {
+ ACE_ERROR ((LM_ERROR,
+ "(%P|%t) Invalid or nil event channel\n"));
+ return 1;
+ }
+
+ ACE_DEBUG ((LM_DEBUG, "Resolved event service\n"));
+
+ // Now create the history
+ ACE_Sample_History history (iterations);
+ TAO_SYNCH_MUTEX history_mutex;
+
+ // The consumer
+ EC_Latency_Consumer consumer (&history,
+ &history_mutex,
+ iterations);
+ // Connect the consumer
+
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ ec->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::ProxyPushSupplier_var proxy_supplier =
+ consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventComm::PushConsumer_var consumer_reference =
+ consumer._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Simple subscription, but usually the helper classes in
+ // $TAO_ROOT/orbsvcs/Event_Utils.h are a better way to do this.
+ RtecEventChannelAdmin::ConsumerQOS consumer_qos;
+ consumer_qos.dependencies.length (2);
+ RtecEventComm::EventHeader& h0 =
+ consumer_qos.dependencies[0].event.header;
+ h0.type = ACE_ES_DISJUNCTION_DESIGNATOR;
+ h0.source = 1;
+
+ RtecEventComm::EventHeader& h1 =
+ consumer_qos.dependencies[1].event.header;
+ h1.type = ACE_ES_EVENT_UNDEFINED; // first free event type
+ h1.source = ACE_ES_EVENT_SOURCE_ANY;
+
+ proxy_supplier->connect_push_consumer (consumer_reference.in (),
+ consumer_qos
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG, "Connected consumer\n"));
+
+ // The supplier
+ EC_Latency_Supplier supplier;
+
+ // The canonical protocol to connect to the EC
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ ec->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::ProxyPushConsumer_var proxy_consumer =
+ supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventComm::PushSupplier_var supplier_reference =
+ supplier._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Simple publication, but usually the helper classes in
+ // $TAO_ROOT/orbsvcs/Event_Utils.h are a better way to do this.
+ RtecEventChannelAdmin::SupplierQOS supplier_qos;
+ supplier_qos.publications.length (1);
+ RtecEventComm::EventHeader& sh0 =
+ supplier_qos.publications[0].event.header;
+ sh0.type = ACE_ES_EVENT_UNDEFINED; // first free event type
+ sh0.source = 1; // first free event source
+
+ proxy_consumer->connect_push_supplier (supplier_reference.in (),
+ supplier_qos
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG, "Connected supplier\n"));
+
+ Task task (proxy_consumer.in (), iterations);
+
+ task.activate ();
+
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+ while (!task.done () || !consumer.done ())
+ {
+ ACE_Time_Value tv (1, 0);
+ orb->run (tv ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_hrtime_t end = ACE_OS::gethrtime ();
+
+ ACE_Thread_Manager::instance ()->wait ();
+
+ // Calibrate the high resolution timer *before* starting the
+ // test.
+ ACE_DEBUG ((LM_DEBUG, "Calibrating high res timer ...."));
+ ACE_High_Res_Timer::calibrate ();
+
+ ACE_UINT32 gsf = ACE_High_Res_Timer::global_scale_factor ();
+ ACE_DEBUG ((LM_DEBUG, "Done (%d)\n", gsf));
+ if (do_dump_history)
+ {
+ history.dump_samples ("HISTORY", gsf);
+ }
+
+ ACE_Basic_Stats stats;
+ history.collect_basic_stats (stats);
+ stats.dump_results ("Latency", gsf);
+
+ ACE_hrtime_t elapsed_microseconds = (end - start) / gsf;
+ double elapsed_seconds =
+ ACE_CU64_TO_CU32(elapsed_microseconds) / 1000000.0;
+ double throughput =
+ double(iterations) / elapsed_seconds;
+
+ ACE_DEBUG ((LM_DEBUG, "Throughtput: %f\n", throughput));
+
+ proxy_supplier->disconnect_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ proxy_consumer->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ PortableServer::ObjectId_var id;
+
+ id = root_poa->servant_to_id (&consumer ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ root_poa->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ id = root_poa->servant_to_id (&supplier ACE_ENV_ARG_PARAMETER);
+ root_poa->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (CORBA::Exception, ex)
+ {
+ ACE_PRINT_EXCEPTION (ex, argv[0]);
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+// ****************************************************************
+
+int
+parse_args (int argc, char *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, "hi:k:");
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'h':
+ do_dump_history = 1;
+ break;
+
+ case 'i':
+ iterations = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+
+ case 'k':
+ ec_ior = get_opts.opt_arg ();
+ break;
+
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-i <iterations>"
+ "-k <IOR>"
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates sucessful parsing of the command line
+ return 0;
+}
+
+// ****************************************************************
+
+EC_Latency_Consumer::EC_Latency_Consumer (ACE_Sample_History *history,
+ TAO_SYNCH_MUTEX *mutex,
+ int message_count)
+ : history_ (history)
+ , mutex_ (mutex)
+ , remaining_messages_ (message_count)
+{
+}
+
+int
+EC_Latency_Consumer::done (void)
+{
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, *this->mutex_, -1);
+ return this->remaining_messages_ <= 0;
+}
+
+void
+EC_Latency_Consumer::push (const RtecEventComm::EventSet& events
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ ACE_hrtime_t creation;
+ ORBSVCS_Time::TimeT_to_hrtime (creation,
+ events[0].header.creation_time);
+ ACE_hrtime_t now = ACE_OS::gethrtime ();
+
+ ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, *this->mutex_);
+ this->history_->sample (now - creation);
+ if (this->remaining_messages_ % 1000 == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Only %d messages to go\n",
+ this->remaining_messages_));
+ }
+
+ this->remaining_messages_--;
+}
+
+void
+EC_Latency_Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+}
+
+// ****************************************************************
+
+EC_Latency_Supplier::EC_Latency_Supplier (void)
+{
+}
+
+void
+EC_Latency_Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+}
+
+// ****************************************************************
+
+Task::Task (RtecEventChannelAdmin::ProxyPushConsumer_ptr consumer,
+ int iterations)
+ : consumer_ (RtecEventChannelAdmin::ProxyPushConsumer::_duplicate (consumer))
+ , remaining_messages_ (iterations)
+{
+}
+
+int
+Task::done (void)
+{
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->mutex_, 1);
+ return this->remaining_messages_ == 0;
+}
+
+int
+Task::svc (void)
+{
+ ACE_TRY_NEW_ENV
+ {
+ RtecEventComm::EventSet event (1);
+ event.length (1);
+ event[0].header.type = ACE_ES_EVENT_UNDEFINED;
+ event[0].header.source = 1;
+ event[0].header.ttl = 1;
+ event[0].data.payload.length(1024);
+
+ for (;;)
+ {
+ ACE_hrtime_t creation = ACE_OS::gethrtime ();
+ ORBSVCS_Time::hrtime_to_TimeT (event[0].header.creation_time,
+ creation);
+ this->consumer_->push (event ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // ACE_Time_Value tv (0, 5000);
+ // ACE_OS::sleep (tv);
+
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->mutex_, -1);
+ if (this->remaining_messages_ % 1000 == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Only %d messages to go\n",
+ this->remaining_messages_));
+ }
+
+ this->remaining_messages_--;
+ if (this->remaining_messages_ == 0)
+ return 0;
+ }
+ }
+ ACE_CATCH (CORBA::SystemException, ex)
+ {
+ ACE_PRINT_EXCEPTION (ex, "Task::svc");
+ }
+ ACE_ENDTRY;
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Performance/Latency.h b/TAO/orbsvcs/tests/Event/Performance/Latency.h
new file mode 100644
index 00000000000..96a182baa25
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/Latency.h
@@ -0,0 +1,100 @@
+/* -*- C++ -*- */
+// $Id$
+//
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS Real-time Event Channel testsuite
+//
+// = FILENAME
+// Latency
+//
+// = AUTHOR
+// Carlos O'Ryan (coryan@cs.wustl.edu)
+//
+// ============================================================================
+
+#ifndef EC_LATENCY_H
+#define EC_LATENCY_H
+
+#include "orbsvcs/RtecEventCommS.h"
+#include "orbsvcs/RtecEventChannelAdminC.h"
+#include "ace/Task.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+class ACE_Sample_History;
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+/// Simple consumer, receives events and record roundtrip delays.
+class EC_Latency_Consumer : public POA_RtecEventComm::PushConsumer
+{
+public:
+ /// Constructor
+ EC_Latency_Consumer (ACE_Sample_History *history,
+ TAO_SYNCH_MUTEX *mutex,
+ int message_count);
+
+ /// Return 1 when all the messages have been received
+ int done (void);
+
+ virtual void push (const RtecEventComm::EventSet& events
+ ACE_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+private:
+ /// Roundtrip delays are recorded here
+ ACE_Sample_History *history_;
+
+ /// Use this mutex to synchronize access to history_
+ TAO_SYNCH_MUTEX *mutex_;
+
+ /// Number of messages yet to be received
+ int remaining_messages_;
+};
+
+// ****************************************************************
+
+class EC_Latency_Supplier : public POA_RtecEventComm::PushSupplier
+{
+public:
+ /// Constructor
+ EC_Latency_Supplier (void);
+
+ virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+};
+
+// ****************************************************************
+
+/// Send events in another thread
+class Task : public ACE_Task_Base
+{
+public:
+ /// Constructor
+ Task (RtecEventChannelAdmin::ProxyPushConsumer_ptr consumer,
+ int iterations);
+
+ /// Return 1 when all the messages have been sent
+ int done (void);
+
+ /// Run the experiment
+ int svc (void);
+
+private:
+ /// The consumer
+ RtecEventChannelAdmin::ProxyPushConsumer_var consumer_;
+
+ /// Number of messages that have to be sent
+ int remaining_messages_;
+
+ /// Synchronize access to remaining_messages_
+ TAO_SYNCH_MUTEX mutex_;
+};
+
+#endif /* EC_LATENCY_H */
diff --git a/TAO/orbsvcs/tests/Event/Performance/Latency_Server.cpp b/TAO/orbsvcs/tests/Event/Performance/Latency_Server.cpp
new file mode 100644
index 00000000000..524d4301164
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/Latency_Server.cpp
@@ -0,0 +1,180 @@
+// $Id$
+
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+
+#include "tao/Messaging/Messaging.h"
+#include "tao/Strategies/advanced_resource.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "ace/High_Res_Timer.h"
+#include "ace/Get_Opt.h"
+#include "ace/Sample_History.h"
+#include "ace/Sched_Params.h"
+#include "ace/OS_NS_errno.h"
+
+ACE_RCSID(EC_Tests_Performance, Latency_Server, "$Id$")
+
+const char *ior_file_name = "ec.ior";
+
+/// Parse the arguments.
+static int parse_args (int argc, char *argv[]);
+
+int
+main (int argc, char *argv [])
+{
+ TAO_EC_Default_Factory::init_svcs ();
+
+ int priority =
+ (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO)
+ + ACE_Sched_Params::priority_max (ACE_SCHED_FIFO)) / 2;
+ priority = ACE_Sched_Params::next_priority (ACE_SCHED_FIFO,
+ priority);
+ // Enable FIFO scheduling, e.g., RT scheduling class on Solaris.
+
+ if (ACE_OS::sched_params (ACE_Sched_Params (ACE_SCHED_FIFO,
+ priority,
+ ACE_SCOPE_PROCESS)) != 0)
+ {
+ if (ACE_OS::last_error () == EPERM)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "server (%P|%t): user is not superuser, "
+ "test runs in time-shared class\n"));
+ }
+ else
+ ACE_ERROR ((LM_ERROR,
+ "server (%P|%t): sched_params failed\n"));
+ }
+
+ ACE_TRY_NEW_ENV
+ {
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+#if (TAO_HAS_CORBA_MESSAGING == 1)
+ CORBA::Object_var manager_object =
+ orb->resolve_initial_references ("ORBPolicyManager"
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::PolicyManager_var policy_manager =
+ CORBA::PolicyManager::_narrow (manager_object.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::Any sync_scope;
+ sync_scope <<= Messaging::SYNC_WITH_TARGET;
+
+ CORBA::PolicyList policy_list (1);
+ policy_list.length (1);
+ policy_list[0] =
+ orb->create_policy (Messaging::SYNC_SCOPE_POLICY_TYPE,
+ sync_scope
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ policy_manager->set_policy_overrides (policy_list,
+ CORBA::SET_OVERRIDE
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+#else
+ ACE_DEBUG ((LM_DEBUG,
+ "CORBA Messaging disabled in this configuration,"
+ " test may not be optimally configured\n"));
+#endif /* TAO_HAS_MESSAGING */
+
+ CORBA::Object_var poa_object =
+ orb->resolve_initial_references("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (poa_object.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ " (%P|%t) Unable to initialize the POA.\n"),
+ 1);
+
+ PortableServer::POA_var root_poa =
+ PortableServer::POA::_narrow (poa_object.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ PortableServer::POAManager_var poa_manager =
+ root_poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ TAO_EC_Event_Channel_Attributes attr (root_poa.in (),
+ root_poa.in ());
+ TAO_EC_Event_Channel ec_impl (attr);
+ ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ RtecEventChannelAdmin::EventChannel_var ec =
+ ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::String_var str =
+ orb->object_to_string (ec.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (ior_file_name != 0)
+ {
+ FILE *output_file= ACE_OS::fopen (ior_file_name, "w");
+ if (output_file == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot open output file for writing IOR: %s",
+ ior_file_name),
+ 1);
+ ACE_OS::fprintf (output_file, "%s", str.in ());
+ ACE_OS::fclose (output_file);
+ }
+
+ orb->run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ PortableServer::ObjectId_var id =
+ root_poa->servant_to_id (&ec_impl ACE_ENV_ARG_PARAMETER);
+ root_poa->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (CORBA::Exception, ex)
+ {
+ ACE_PRINT_EXCEPTION (ex, argv[0]);
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+// ****************************************************************
+
+int
+parse_args (int argc, char *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, "o:");
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'o':
+ ior_file_name = get_opts.opt_arg ();
+ break;
+
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-o <ior_file_name>"
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates sucessful parsing of the command line
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/Performance/Makefile.am b/TAO/orbsvcs/tests/Event/Performance/Makefile.am
new file mode 100644
index 00000000000..b37e6f11b58
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/Makefile.am
@@ -0,0 +1,229 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## ../bin/mwc.pl -type automake -noreldefs TAO.mwc
+
+ACE_BUILDDIR = $(top_builddir)/..
+ACE_ROOT = $(top_srcdir)/..
+TAO_BUILDDIR = $(top_builddir)
+TAO_ROOT = $(top_srcdir)
+
+noinst_PROGRAMS =
+
+## Makefile.Event_Performance_Connect.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Connect
+
+Connect_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Connect_SOURCES = \
+ Connect.cpp \
+ Connect.h
+
+Connect_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Performance_Inversion.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Inversion
+
+Inversion_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Inversion_SOURCES = \
+ Inversion.cpp \
+ Inversion.h
+
+Inversion_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Performance_Latency.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Latency
+
+Latency_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Latency_SOURCES = \
+ Latency.cpp \
+ Latency.h
+
+Latency_LDADD = \
+ $(TAO_BUILDDIR)/tao/libTAO_Strategies.la \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Performance_Latency_Server.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Latency_Server
+
+Latency_Server_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Latency_Server_SOURCES = \
+ Latency_Server.cpp \
+ Connect.h \
+ Inversion.h \
+ Latency.h \
+ Throughput.h
+
+Latency_Server_LDADD = \
+ $(TAO_BUILDDIR)/tao/libTAO_Strategies.la \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.Event_Performance_Throughput.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += Throughput
+
+Throughput_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(srcdir)/../lib
+
+Throughput_SOURCES = \
+ Throughput.cpp \
+ Throughput.h
+
+Throughput_LDADD = \
+ $(top_builddir)/orbsvcs/tests/Event/lib/libECTests.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/TAO/orbsvcs/tests/Event/Performance/README b/TAO/orbsvcs/tests/Event/Performance/README
new file mode 100644
index 00000000000..2a62f56080a
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/README
@@ -0,0 +1,50 @@
+# $Id$
+
+ Performance tests for the real-time event channel.
+
+This directory contains several tests to measure the performance of
+the real-time event channel. Remember to compile ACE and TAO with
+optimizations enabled when running this tests.
+
+ Here are some canonical test configurations:
+
+# Measure throughput and latency, in a configuration suitable for
+# single threaded systems. This is probably the best case scenario,
+# one supplier, one consumer and no locking.
+
+$ Throughput -burstsize 100000 -burstcount 1
+
+# Same test as above, but with a configuration that is MT-safe
+
+$ Throughput -ORBsvcconf ec.st.conf -burstsize 100000 -burstcount 1
+
+# Increase the number of consumers, but only the first one receives
+# events.
+
+$ Throughput -ORBsvcconf ec.st.conf -burstsize 100000 -burstcount 1 \
+ -consumers 4
+
+# Now increase the number of suppliers, only one consumer receives
+# events from each supplier.
+
+$ Throughput -ORBsvcconf ec.st.conf -burstsize 100000 -burstcount 1 \
+ -consumers 4 -suppliers 4
+
+# Now a test where all consumers receive events from all suppliers
+
+$ Throughput -ORBsvcconf ec.st.conf -burstsize 100000 -burstcount 1 \
+ -consumers 4 -suppliers 4 -consumers_tshift 0 -suppliers_tshift 0
+
+
+# Measure the time required to connect the 100 consumers and 100
+# suppliers, inserting one supplier first and then one supplier.
+# Try -connection_order "consumers" or "suppliers"
+
+$ Connect -ORBsvcconf ec.st.conf -consumers 100 -suppliers 100 \
+ -connection_order interleaved
+
+
+NOTES
+
+ Don't worry about the "incomplete data" warning, it is a
+deffect in the test.
diff --git a/TAO/orbsvcs/tests/Event/Performance/Throughput.cpp b/TAO/orbsvcs/tests/Event/Performance/Throughput.cpp
new file mode 100644
index 00000000000..513434e07f9
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/Throughput.cpp
@@ -0,0 +1,61 @@
+// $Id$
+
+#include "Throughput.h"
+#include "Consumer.h"
+#include "Supplier.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+#include "ace/Get_Opt.h"
+
+ACE_RCSID (EC_Tests_Performance,
+ Throughput,
+ "$Id$")
+
+int
+main (int argc, char *argv [])
+{
+ EC_Throughput driver;
+ return driver.run (argc, argv);
+}
+
+// ****************************************************************
+
+EC_Throughput::EC_Throughput (void)
+{
+}
+
+int
+EC_Throughput::parse_args (int& argc, char* argv[])
+{
+ if (this->EC_Driver::parse_args (argc, argv) != 0)
+ return -1;
+ return 0;
+}
+
+void
+EC_Throughput::print_args (void) const
+{
+ this->EC_Driver::print_args ();
+}
+
+void
+EC_Throughput::print_usage (void)
+{
+ this->EC_Driver::print_usage ();
+}
+
+void
+EC_Throughput::modify_attributes (TAO_EC_Event_Channel_Attributes&)
+{
+}
+
+void
+EC_Throughput::execute_test (ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->EC_Driver::execute_test (ACE_ENV_SINGLE_ARG_PARAMETER);
+}
+
+void
+EC_Throughput::dump_results (void)
+{
+ this->EC_Driver::dump_results ();
+}
diff --git a/TAO/orbsvcs/tests/Event/Performance/Throughput.h b/TAO/orbsvcs/tests/Event/Performance/Throughput.h
new file mode 100644
index 00000000000..f3d5ee6cc04
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/Throughput.h
@@ -0,0 +1,56 @@
+/* -*- C++ -*- */
+// $Id$
+//
+// ============================================================================
+//
+// = LIBRARY
+// ORBSVCS Real-time Event Channel testsuite
+//
+// = FILENAME
+// Throughput
+//
+// = AUTHOR
+// Carlos O'Ryan (coryan@cs.wustl.edu)
+//
+// ============================================================================
+
+#ifndef EC_THROUGHPUT_H
+#define EC_THROUGHPUT_H
+
+#include "Driver.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class EC_Throughput : public EC_Driver
+{
+ //
+ // = TITLE
+ // Test the EC throughput
+ //
+ // = DESCRIPTION
+ //
+public:
+ EC_Throughput (void);
+ // Constructor
+
+ // = The EC_Driver methods
+ virtual int parse_args (int& argc, char* argv[]);
+ virtual void print_args (void) const;
+ virtual void print_usage (void);
+ // add some command line args to enable/disable throughputions
+
+ virtual void modify_attributes (TAO_EC_Event_Channel_Attributes& attr);
+ // set the throughpution flags
+
+ void execute_test (ACE_ENV_SINGLE_ARG_DECL);
+ // Don't run the suppliers, just test connect and disconnect calls.
+
+ void dump_results (void);
+ // Don't dump the EC_Driver results, they are meaningless.
+
+private:
+};
+
+#endif /* EC_THROUGHPUT_H */
diff --git a/TAO/orbsvcs/tests/Event/Performance/ec.list.conf b/TAO/orbsvcs/tests/Event/Performance/ec.list.conf
new file mode 100644
index 00000000000..5c28ef28fec
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/ec.list.conf
@@ -0,0 +1,2 @@
+# $Id$
+static EC_Factory "-ECProxyPushConsumerCollection st:delayed:list -ECProxyPushSupplierCollection st:delayed:list -ECdispatching reactive -ECfiltering null -ECproxyconsumerlock null -ECproxysupplierlock null -ECsupplierfiltering null"
diff --git a/TAO/orbsvcs/tests/Event/Performance/ec.list.conf.xml b/TAO/orbsvcs/tests/Event/Performance/ec.list.conf.xml
new file mode 100644
index 00000000000..0ca6716f58b
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/ec.list.conf.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0'?>
+<!-- Converted from ./orbsvcs/tests/Event/Performance/ec.list.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- $Id$ -->
+ <static id="EC_Factory" params="-ECProxyPushConsumerCollection st:delayed:list -ECProxyPushSupplierCollection st:delayed:list -ECdispatching reactive -ECfiltering null -ECproxyconsumerlock null -ECproxysupplierlock null -ECsupplierfiltering null"/>
+</ACE_Svc_Conf>
diff --git a/TAO/orbsvcs/tests/Event/Performance/ec.mt.conf b/TAO/orbsvcs/tests/Event/Performance/ec.mt.conf
new file mode 100644
index 00000000000..c9583c1847d
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/ec.mt.conf
@@ -0,0 +1,2 @@
+# $Id$
+static EC_Factory "-ECProxyPushConsumerCollection mt:immediate:list -ECProxyPushSupplierCollection mt:immediate:list -ECDispatching mt -ECfiltering basic -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"
diff --git a/TAO/orbsvcs/tests/Event/Performance/ec.mt.conf.xml b/TAO/orbsvcs/tests/Event/Performance/ec.mt.conf.xml
new file mode 100644
index 00000000000..cd1467b5bed
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/ec.mt.conf.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0'?>
+<!-- Converted from ./orbsvcs/tests/Event/Performance/ec.mt.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- $Id$ -->
+ <static id="EC_Factory" params="-ECProxyPushConsumerCollection mt:immediate:list -ECProxyPushSupplierCollection mt:immediate:list -ECDispatching mt -ECfiltering basic -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"/>
+</ACE_Svc_Conf>
diff --git a/TAO/orbsvcs/tests/Event/Performance/ec.rb_tree.conf b/TAO/orbsvcs/tests/Event/Performance/ec.rb_tree.conf
new file mode 100644
index 00000000000..1032eb4807c
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/ec.rb_tree.conf
@@ -0,0 +1,2 @@
+# $Id$
+static EC_Factory "-ECProxyPushConsumerCollection st:delayed:rb_tree -ECProxyPushSupplierCollection st:delayed:rb_tree -ECdispatching reactive -ECfiltering null -ECproxyconsumerlock null -ECproxysupplierlock null -ECsupplierfiltering null"
diff --git a/TAO/orbsvcs/tests/Event/Performance/ec.rb_tree.conf.xml b/TAO/orbsvcs/tests/Event/Performance/ec.rb_tree.conf.xml
new file mode 100644
index 00000000000..25f61beac48
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/ec.rb_tree.conf.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0'?>
+<!-- Converted from ./orbsvcs/tests/Event/Performance/ec.rb_tree.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- $Id$ -->
+ <static id="EC_Factory" params="-ECProxyPushConsumerCollection st:delayed:rb_tree -ECProxyPushSupplierCollection st:delayed:rb_tree -ECdispatching reactive -ECfiltering null -ECproxyconsumerlock null -ECproxysupplierlock null -ECsupplierfiltering null"/>
+</ACE_Svc_Conf>
diff --git a/TAO/orbsvcs/tests/Event/Performance/ec.st.conf b/TAO/orbsvcs/tests/Event/Performance/ec.st.conf
new file mode 100644
index 00000000000..6e185e74acb
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/ec.st.conf
@@ -0,0 +1,2 @@
+# $Id$
+static EC_Factory "-ECProxyPushConsumerCollection st:immediate:list -ECProxyPushSupplierCollection st:immediate:list -ECdispatching reactive -ECfiltering null -ECproxyconsumerlock null -ECproxysupplierlock null -ECsupplierfiltering null"
diff --git a/TAO/orbsvcs/tests/Event/Performance/ec.st.conf.xml b/TAO/orbsvcs/tests/Event/Performance/ec.st.conf.xml
new file mode 100644
index 00000000000..16f28063d63
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/ec.st.conf.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0'?>
+<!-- Converted from ./orbsvcs/tests/Event/Performance/ec.st.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- $Id$ -->
+ <static id="EC_Factory" params="-ECProxyPushConsumerCollection st:immediate:list -ECProxyPushSupplierCollection st:immediate:list -ECdispatching reactive -ECfiltering null -ECproxyconsumerlock null -ECproxysupplierlock null -ECsupplierfiltering null"/>
+</ACE_Svc_Conf>
diff --git a/TAO/orbsvcs/tests/Event/Performance/eventperftestexe.mpb b/TAO/orbsvcs/tests/Event/Performance/eventperftestexe.mpb
new file mode 100644
index 00000000000..67e95079156
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/eventperftestexe.mpb
@@ -0,0 +1,13 @@
+// -*- MPC -*-
+// $Id$
+
+project: messaging, rteventexe, rtevent_serv, naming, iortable {
+ after += Event_Test_Lib
+ libs += ECTests
+
+ specific (automake) {
+ includes += $(srcdir)/../lib
+ } else {
+ includes += ../lib
+ }
+}
diff --git a/TAO/orbsvcs/tests/Event/Performance/latency.conf b/TAO/orbsvcs/tests/Event/Performance/latency.conf
new file mode 100644
index 00000000000..35359a852cb
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/latency.conf
@@ -0,0 +1,4 @@
+# $Id$
+# tp is now the default reactor type
+# static Resource_Factory "-ORBReactorType tp"
+static Client_Strategy_Factory "-ORBClientConnectionHandler RW"
diff --git a/TAO/orbsvcs/tests/Event/Performance/latency.conf.xml b/TAO/orbsvcs/tests/Event/Performance/latency.conf.xml
new file mode 100644
index 00000000000..068e45df3d0
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/latency.conf.xml
@@ -0,0 +1,8 @@
+<?xml version='1.0'?>
+<!-- Converted from ./orbsvcs/tests/Event/Performance/latency.conf by svcconf-convert.pl -->
+<ACE_Svc_Conf>
+ <!-- $Id$ -->
+ <!-- tp is now the default reactor type -->
+ <!-- static Resource_Factory "-ORBReactorType tp" -->
+ <static id="Client_Strategy_Factory" params="-ORBClientConnectionHandler RW"/>
+</ACE_Svc_Conf>
diff --git a/TAO/orbsvcs/tests/Event/Performance/run_test.pl b/TAO/orbsvcs/tests/Event/Performance/run_test.pl
new file mode 100755
index 00000000000..bde6790200e
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/Performance/run_test.pl
@@ -0,0 +1,65 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+# This is a Perl script that runs the client and all the other servers that
+# are needed
+
+use lib '../../../../../bin';
+use PerlACE::Run_Test;
+
+$status = 0;
+
+$ec_st_conf = PerlACE::LocalFile ("ec.st$PerlACE::svcconf_ext");
+
+sub RunTest ($$$)
+{
+ my $message = shift;
+ my $program = shift;
+ my $arguments = shift;
+
+ my $TEST = new PerlACE::Process ($program, $arguments);
+
+ print STDERR "\n\n$message\n";
+
+ my $test = $TEST->SpawnWaitKill (60);
+
+ if ($test != 0) {
+ print STDERR "ERROR: Test returned $test\n";
+ $status = 1;
+ }
+}
+
+RunTest ("\n\nThroughput/Latency single threaded configuration\n",
+ "Throughput",
+ "-ORBsvcconf $ec_st_conf -burstsize 2000 -burstcount 1");
+
+RunTest ("\n\nThroughput/Latency MT-safe configuration\n",
+ "Throughput",
+ "-burstsize 2000 -burstcount 1");
+
+RunTest ("\n\nThroughput/Latency MT-safe configuration, 4 consumers\n",
+ "Throughput",
+ "-burstsize 2000 -burstcount 1 -consumers 4");
+
+RunTest ("\n\nThroughput/Latency MT-safe configuration, 4 consumers 4 suppliers\n",
+ "Throughput",
+ "-burstsize 2000 -burstcount 1 -consumers 4 -suppliers 4");
+
+RunTest ("\n\nThroughput/Latency MT-safe configuration, 4 consumers 4 suppliers\n",
+ "Throughput",
+ "-burstsize 2000 -burstcount 1 -consumers 4 -suppliers 4"
+ . " -consumers_tshift 0 -suppliers_tshift 0");
+
+RunTest ("\n\nConnection and disconnection time, 100 consumers 100 suppliers\n",
+ "Connect",
+ "-consumers 100 -suppliers 100 -connection_order interleaved");
+
+RunTest ("\n\nConnection and disconnection time, 500 consumers 500 suppliers\n",
+ "Connect",
+ "-consumers 500 -suppliers 500 -connection_order interleaved");
+
+exit $status;
diff --git a/TAO/orbsvcs/tests/Event/lib/Consumer.cpp b/TAO/orbsvcs/tests/Event/lib/Consumer.cpp
new file mode 100644
index 00000000000..1b04ac6a4c5
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/lib/Consumer.cpp
@@ -0,0 +1,167 @@
+// $Id$
+
+#include "Consumer.h"
+#include "orbsvcs/Event_Service_Constants.h"
+#include "orbsvcs/Time_Utilities.h"
+
+#include "tao/debug.h"
+
+ACE_RCSID (EC_Tests,
+ EC_Consumer,
+ "$Id$")
+
+EC_Consumer::EC_Consumer (EC_Driver *driver,
+ void *cookie)
+ : driver_ (driver),
+ cookie_ (cookie),
+ push_count_ (0),
+ shutdown_event_type_ (ACE_ES_EVENT_SHUTDOWN),
+ is_active_ (0)
+{
+}
+
+void
+EC_Consumer::connect (
+ RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin,
+ const RtecEventChannelAdmin::ConsumerQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL)
+{
+ this->supplier_proxy_ =
+ consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->connect (qos, shutdown_event_type ACE_ENV_ARG_PARAMETER);
+}
+
+void
+EC_Consumer::connect (
+ const RtecEventChannelAdmin::ConsumerQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL)
+{
+ if (CORBA::is_nil (this->supplier_proxy_.in ()))
+ return; // @@ Throw?
+
+ this->shutdown_event_type_ = shutdown_event_type;
+
+ if (CORBA::is_nil (this->myself_.in ()))
+ {
+ this->myself_ = this->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ this->is_active_ = 1;
+
+ this->supplier_proxy_->connect_push_consumer (this->myself_.in (),
+ qos
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+int
+EC_Consumer::connected (void) const
+{
+ return !CORBA::is_nil (this->supplier_proxy_.in ());
+}
+
+void
+EC_Consumer::disconnect (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (CORBA::is_nil (this->supplier_proxy_.in ()))
+ return;
+
+ this->supplier_proxy_->disconnect_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->supplier_proxy_ =
+ RtecEventChannelAdmin::ProxyPushSupplier::_nil ();
+}
+
+void
+EC_Consumer::shutdown (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (!this->is_active_)
+ return;
+
+ // Deactivate the servant
+ PortableServer::POA_var poa =
+ this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ PortableServer::ObjectId_var id =
+ poa->servant_to_id (this ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ poa->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ this->myself_ = RtecEventComm::PushConsumer::_nil ();
+ this->is_active_ = 0;
+}
+
+void
+EC_Consumer::dump_results (const char* name,
+ ACE_UINT32 gsf)
+{
+ this->throughput_.dump_results (name, gsf);
+}
+
+void
+EC_Consumer::accumulate (ACE_Throughput_Stats& throughput) const
+{
+ throughput.accumulate (this->throughput_);
+}
+
+void
+EC_Consumer::push (const RtecEventComm::EventSet& events
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ this->driver_->consumer_push (this->cookie_, events ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (events.length () == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "EC_Consumer (%P|%t) no events\n"));
+ return;
+ }
+
+ ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock_);
+ if (this->push_count_ == 0)
+ this->throughput_start_ = ACE_OS::gethrtime ();
+
+ this->push_count_ += events.length ();
+
+ if (TAO_debug_level > 0
+ && this->push_count_ % 100 == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "EC_Consumer (%P|%t): %d events received\n",
+ this->push_count_));
+ }
+
+ for (u_int i = 0; i < events.length (); ++i)
+ {
+ const RtecEventComm::Event& e = events[i];
+
+ ACE_hrtime_t creation;
+ ORBSVCS_Time::TimeT_to_hrtime (creation,
+ e.header.creation_time);
+
+ const ACE_hrtime_t now = ACE_OS::gethrtime ();
+ this->throughput_.sample (now - this->throughput_start_,
+ now - creation);
+
+ if (e.header.type == this->shutdown_event_type_)
+ this->driver_->consumer_shutdown (this->cookie_ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+}
+
+void
+EC_Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ this->driver_->consumer_disconnect (this->cookie_ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ this->supplier_proxy_ =
+ RtecEventChannelAdmin::ProxyPushSupplier::_nil ();
+}
diff --git a/TAO/orbsvcs/tests/Event/lib/Consumer.h b/TAO/orbsvcs/tests/Event/lib/Consumer.h
new file mode 100644
index 00000000000..439b95f9747
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/lib/Consumer.h
@@ -0,0 +1,121 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file Consumer.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan (coryan@cs.wustl.edu)
+ */
+//=============================================================================
+
+
+#ifndef EC_CONSUMER_H
+#define EC_CONSUMER_H
+
+#include "Driver.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "orbsvcs/RtecEventCommS.h"
+#include "orbsvcs/RtecEventChannelAdminC.h"
+#include "ace/OS_NS_time.h"
+
+/**
+ * @class EC_Consumer
+ *
+ * @brief Simple consumer object to implement EC tests.
+ *
+ * This class is a consumer of events.
+ * 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.
+ */
+class EC_Test_Export EC_Consumer : public POA_RtecEventComm::PushConsumer
+{
+public:
+ /// Constructor
+ EC_Consumer (EC_Driver* driver, void* cookie);
+
+ /// The driver program can build the QoS attributes and obtain the
+ /// ConsumerAdmin, we do the rest.
+ virtual void connect (
+ RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin,
+ const RtecEventChannelAdmin::ConsumerQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL);
+
+ /**
+ * The driver program can build the QoS attributes and we use
+ * whatevet supplier_proxy we already have (useful for reconnection
+ * tests).
+ */
+ virtual void connect (
+ const RtecEventChannelAdmin::ConsumerQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL);
+
+ /// returns 0 if it is not connected
+ virtual int connected (void) const;
+
+ /// The application can invoke this method to disconnect from the EC
+ /// and deactivate this class.
+ void disconnect (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// The application is shutting down, deactivate the consumer.
+ void shutdown (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Accumulate our statistics to the totals.
+ void accumulate (ACE_Throughput_Stats& throughput) const;
+
+ /// Printout the statistics
+ virtual void dump_results (const char* name,
+ ACE_UINT32 global_scale_factor);
+
+ // = The RtecEventComm::PushConsumer methods
+
+ /// The skeleton 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));
+
+private:
+ /// The main driver for the test.
+ EC_Driver* driver_;
+
+ /// A magic cookie passed by the driver that we pass back in our
+ /// callbacks.
+ void* cookie_;
+
+ /// We talk to the EC using this proxy.
+ RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy_;
+
+ /// Protect internal state
+ TAO_SYNCH_MUTEX lock_;
+
+ /// The timestamp for the first message received
+ ACE_hrtime_t throughput_start_;
+
+ /// Used for reporting stats
+ ACE_Throughput_Stats throughput_;
+
+ /// The number of push() calls
+ int push_count_;
+
+ /// The type used to indicate shutdown
+ int shutdown_event_type_;
+
+ /// Is the consumer active in the POA?
+ int is_active_;
+
+ /// Cache the object reference to speed up connect/disconnect calls.
+ RtecEventComm::PushConsumer_var myself_;
+};
+
+#endif /* ECT_CONSUMER_H */
diff --git a/TAO/orbsvcs/tests/Event/lib/Counting_Consumer.cpp b/TAO/orbsvcs/tests/Event/lib/Counting_Consumer.cpp
new file mode 100644
index 00000000000..22e3480f3ce
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/lib/Counting_Consumer.cpp
@@ -0,0 +1,116 @@
+// $Id$
+
+#include "Counting_Consumer.h"
+
+ACE_RCSID(EC_Tests, EC_Count_Consumer, "$Id$")
+
+EC_Counting_Consumer::EC_Counting_Consumer (const char* name)
+ : event_count (0),
+ disconnect_count (0),
+ name_ (name)
+{
+}
+
+void
+EC_Counting_Consumer::connect (RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin,
+ const RtecEventChannelAdmin::ConsumerQOS &qos
+ ACE_ENV_ARG_DECL)
+{
+ // The canonical protocol to connect to the EC
+
+ RtecEventComm::PushConsumer_var consumer =
+ this->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (CORBA::is_nil (this->supplier_proxy_.in ()))
+ {
+ this->supplier_proxy_ =
+ consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ this->supplier_proxy_->connect_push_consumer (consumer.in (),
+ qos
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+EC_Counting_Consumer::disconnect (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (!CORBA::is_nil (this->supplier_proxy_.in ()))
+ {
+ this->supplier_proxy_->disconnect_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ this->supplier_proxy_ =
+ RtecEventChannelAdmin::ProxyPushSupplier::_nil ();
+ }
+ this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
+}
+
+void
+EC_Counting_Consumer::deactivate (ACE_ENV_SINGLE_ARG_DECL)
+{
+ PortableServer::POA_var consumer_poa =
+ this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ PortableServer::ObjectId_var consumer_id =
+ consumer_poa->servant_to_id (this ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ consumer_poa->deactivate_object (consumer_id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+}
+
+void
+EC_Counting_Consumer::dump_results (int expected_count, int tolerance)
+{
+ int diff = this->event_count - expected_count;
+ if (diff > tolerance || diff < -tolerance)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ERROR - %s unexpected number of events <%d>\n",
+ this->name_,
+ this->event_count));
+ }
+ else
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "%s - number of events <%d> within margins\n",
+ this->name_,
+ this->event_count));
+ }
+}
+
+void
+EC_Counting_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,
+ "%s (%P|%t) no events\n", this->name_));
+ return;
+ }
+
+ this->event_count ++;
+#if 0
+ if (this->event_count % 10 == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "%s (%P|%t): %d events received\n",
+ this->name_,
+ this->event_count));
+ }
+#endif /* 0 */
+}
+
+void
+EC_Counting_Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ this->disconnect_count++;
+ this->supplier_proxy_ =
+ RtecEventChannelAdmin::ProxyPushSupplier::_nil ();
+}
diff --git a/TAO/orbsvcs/tests/Event/lib/Counting_Consumer.h b/TAO/orbsvcs/tests/Event/lib/Counting_Consumer.h
new file mode 100644
index 00000000000..06878cb4b9f
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/lib/Counting_Consumer.h
@@ -0,0 +1,72 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file Counting_Consumer.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan (coryan@cs.wustl.edu)
+ */
+//=============================================================================
+
+
+#ifndef EC_COUNTING_CONSUMER_H
+#define EC_COUNTING_CONSUMER_H
+
+#include "ectest_export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "orbsvcs/RtecEventCommS.h"
+#include "orbsvcs/RtecEventChannelAdminC.h"
+
+/**
+ * @class EC_Counting_Consumer
+ *
+ * @brief Simple consumer object to implement EC tests.
+ *
+ * This is a simple consumer that counts the events it receives.
+ */
+class EC_Test_Export EC_Counting_Consumer : public POA_RtecEventComm::PushConsumer
+{
+public:
+ /// Constructor
+ EC_Counting_Consumer (const char* name);
+
+ /// Simple connect/disconnect methods..
+ void connect (RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin,
+ const RtecEventChannelAdmin::ConsumerQOS &qos
+ ACE_ENV_ARG_DECL);
+ void disconnect (ACE_ENV_SINGLE_ARG_DECL);
+ void deactivate (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Print out an error message if the event count is too far from the
+ /// expected count.
+ void dump_results (int expected_count, int tolerance);
+
+ // = The RtecEventComm::PushConsumer methods
+
+ /// The skeleton 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));
+
+ /// Keep track of the number of events received.
+ CORBA::ULong event_count;
+
+ /// Keep track of the number of disconnect calls received.
+ CORBA::ULong disconnect_count;
+
+protected:
+ /// The proxy
+ RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy_;
+
+ /// The name
+ const char* name_;
+};
+
+#endif /* ECT_CONSUMER_H */
diff --git a/TAO/orbsvcs/tests/Event/lib/Counting_Supplier.cpp b/TAO/orbsvcs/tests/Event/lib/Counting_Supplier.cpp
new file mode 100644
index 00000000000..59bfbe0b6ac
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/lib/Counting_Supplier.cpp
@@ -0,0 +1,225 @@
+// $Id$
+
+#include "Counting_Supplier.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "ace/OS_NS_unistd.h"
+
+ACE_RCSID (EC_Tests,
+ EC_Count_Supplier,
+ "$Id$")
+
+EC_Counting_Supplier::EC_Counting_Supplier (void)
+ : event_count (0),
+ disconnect_count (0),
+ consumer_adapter_ (this),
+ event_source_ (-1),
+ event_type_ (ACE_ES_EVENT_UNDEFINED)
+{
+}
+
+void
+EC_Counting_Supplier::activate (RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin,
+ int milliseconds
+ ACE_ENV_ARG_DECL)
+{
+ RtecEventComm::PushConsumer_var consumer =
+ this->consumer_adapter_._this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->supplier_proxy_ =
+ consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Let's say that the execution time for event 2 is 1
+ // milliseconds...
+ ACE_Time_Value tv (0, milliseconds * 1000);
+ TimeBase::TimeT time;
+ ORBSVCS_Time::Time_Value_to_TimeT (time, tv);
+
+ ACE_ConsumerQOS_Factory consumer_qos;
+ consumer_qos.start_disjunction_group (1);
+ consumer_qos.insert_time (ACE_ES_EVENT_INTERVAL_TIMEOUT,
+ time,
+ 0);
+
+ this->supplier_proxy_->connect_push_consumer (consumer.in (),
+ consumer_qos.get_ConsumerQOS ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+EC_Counting_Supplier::deactivate (ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->supplier_proxy_->disconnect_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ PortableServer::POA_var consumer_poa =
+ this->consumer_adapter_._default_POA (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ PortableServer::ObjectId_var consumer_id =
+ consumer_poa->servant_to_id (&this->consumer_adapter_ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ consumer_poa->deactivate_object (consumer_id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+EC_Counting_Supplier::connect (
+ RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin,
+ int published_source,
+ int published_type,
+ int event_source,
+ int event_type
+ ACE_ENV_ARG_DECL)
+{
+ this->event_source_ = event_source;
+ this->event_type_ = event_type;
+
+ ACE_SupplierQOS_Factory supplier_qos;
+ supplier_qos.insert (published_source,
+ published_type,
+ 0, 1);
+ this->connect (supplier_admin,
+ supplier_qos.get_SupplierQOS ()
+ ACE_ENV_ARG_PARAMETER);
+}
+
+void
+EC_Counting_Supplier::connect (
+ RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin,
+ const RtecEventChannelAdmin::SupplierQOS &qos
+ ACE_ENV_ARG_DECL)
+{
+ RtecEventComm::PushSupplier_var supplier =
+ this->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (CORBA::is_nil (this->consumer_proxy_.in ()))
+ {
+ this->consumer_proxy_ =
+ supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ this->consumer_proxy_->connect_push_supplier (supplier.in (),
+ qos
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+EC_Counting_Supplier::disconnect (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (!CORBA::is_nil (this->consumer_proxy_.in ()))
+ {
+ this->consumer_proxy_->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ PortableServer::POA_var supplier_poa =
+ this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ PortableServer::ObjectId_var supplier_id =
+ supplier_poa->servant_to_id (this ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ supplier_poa->deactivate_object (supplier_id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->consumer_proxy_ =
+ RtecEventChannelAdmin::ProxyPushConsumer::_nil ();
+}
+
+void
+EC_Counting_Supplier::push (const RtecEventComm::EventSet&
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (CORBA::is_nil (this->consumer_proxy_.in ()))
+ return;
+
+ RtecEventComm::EventSet event (1);
+ event.length (1);
+ event[0].header.source = this->event_source_;
+ event[0].header.type = this->event_type_;
+ event[0].header.ttl = 1;
+
+ this->consumer_proxy_->push (event ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ this->event_count++;
+}
+
+void
+EC_Counting_Supplier::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+}
+
+void
+EC_Counting_Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ this->disconnect_count++;
+ this->consumer_proxy_ =
+ RtecEventChannelAdmin::ProxyPushConsumer::_nil ();
+}
+
+// ****************************************************************
+
+EC_Counting_Supplier_Task::
+ EC_Counting_Supplier_Task (EC_Counting_Supplier *s)
+ : supplier_ (s),
+ stop_flag_ (0),
+ push_count_ (0)
+{
+}
+
+int
+EC_Counting_Supplier_Task::svc ()
+{
+ ACE_TRY_NEW_ENV
+ {
+ this->run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ return -1;
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+void
+EC_Counting_Supplier_Task::stop (void)
+{
+ ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock_);
+ this->stop_flag_ = 1;
+}
+
+CORBA::ULong
+EC_Counting_Supplier_Task::push_count (void)
+{
+ return this->push_count_;
+}
+
+void
+EC_Counting_Supplier_Task::run (ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->event_.length (1);
+
+ int stop = 0;
+ do {
+ this->supplier_->push (this->event_ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Sleep for a short time to avoid spinning...
+ ACE_OS::sleep (0);
+
+ ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock_);
+
+ this->push_count_++;
+
+ stop = this->stop_flag_;
+ } while (stop == 0);
+}
diff --git a/TAO/orbsvcs/tests/Event/lib/Counting_Supplier.h b/TAO/orbsvcs/tests/Event/lib/Counting_Supplier.h
new file mode 100644
index 00000000000..8e6f940daa6
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/lib/Counting_Supplier.h
@@ -0,0 +1,129 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file Counting_Supplier.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan (coryan@cs.wustl.edu)
+ */
+//=============================================================================
+
+
+#ifndef EC_COUNTING_SUPPLIER_H
+#define EC_COUNTING_SUPPLIER_H
+
+#include "ectest_export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "orbsvcs/Channel_Clients_T.h"
+#include "orbsvcs/RtecEventChannelAdminC.h"
+#include "ace/Task.h"
+
+/**
+ * @class EC_Counting_Supplier
+ *
+ * @brief Simple supplier object
+ *
+ * This class is a supplier of events.
+ */
+class EC_Test_Export EC_Counting_Supplier : public POA_RtecEventComm::PushSupplier
+{
+public:
+ /// Constructor
+ EC_Counting_Supplier (void);
+
+ // = The RtecEventComm::PushSupplier methods
+
+ /**
+ * Connect as a consumer to receive a TIMEOUT every <period>
+ * milliseconds.
+ * The class pushes an event (in its supplier role) every time it
+ * receives the timeout.
+ */
+ void activate (RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin,
+ int period
+ ACE_ENV_ARG_DECL);
+ void deactivate (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Simple connect/disconnect methods..
+ void connect (RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin,
+ int published_source,
+ int published_type,
+ int event_source,
+ int event_type
+ ACE_ENV_ARG_DECL);
+ void connect (RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin,
+ const RtecEventChannelAdmin::SupplierQOS &qos
+ ACE_ENV_ARG_DECL);
+ void disconnect (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// The Consumer side methods.
+ void push (const RtecEventComm::EventSet& events
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// The skeleton methods.
+ virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// Count the number of events sent
+ CORBA::ULong event_count;
+
+ /// Count the number of disconnect_push_supplier calls
+ CORBA::ULong disconnect_count;
+
+private:
+ /// Adapter...
+ ACE_PushConsumer_Adapter<EC_Counting_Supplier> consumer_adapter_;
+
+ /// The adapter proxy...
+ RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy_;
+
+ /// Our proxy
+ RtecEventChannelAdmin::ProxyPushConsumer_var consumer_proxy_;
+
+ /// The event source
+ int event_source_;
+
+ /// The event type
+ int event_type_;
+};
+
+class EC_Test_Export EC_Counting_Supplier_Task : public ACE_Task_Base
+{
+public:
+ /// Create the task...
+ EC_Counting_Supplier_Task (EC_Counting_Supplier *supplier);
+
+ // = Check the ACE_Task_Base documentation.
+ int svc (void);
+
+ void stop (void);
+ CORBA::ULong push_count (void);
+
+ /// Run a single iteration of the test
+ void run (ACE_ENV_SINGLE_ARG_DECL);
+
+private:
+ /// The supplier we are turning into an active object
+ EC_Counting_Supplier *supplier_;
+
+ /// The event we push through the supplier
+ RtecEventComm::EventSet event_;
+
+ /// Set to 1 when the test must stop
+ int stop_flag_;
+
+ /// Count the number of push() calls
+ CORBA::ULong push_count_;
+
+ TAO_SYNCH_MUTEX lock_;
+};
+
+#endif /* ECT_SUPPLIER_H */
diff --git a/TAO/orbsvcs/tests/Event/lib/Driver.cpp b/TAO/orbsvcs/tests/Event/lib/Driver.cpp
new file mode 100644
index 00000000000..d74d6f76b84
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/lib/Driver.cpp
@@ -0,0 +1,1027 @@
+// $Id$
+
+#include "Driver.h"
+#include "Consumer.h"
+#include "Supplier.h"
+
+#include "orbsvcs/Event_Service_Constants.h"
+#include "orbsvcs/Event_Utilities.h"
+#include "orbsvcs/Event/EC_Default_Factory.h"
+#include "orbsvcs/Event/EC_Event_Channel.h"
+
+#include "tao/ORB_Constants.h"
+
+#include "ace/Sched_Params.h"
+#include "ace/Arg_Shifter.h"
+#include "ace/High_Res_Timer.h"
+#include "ace/Stats.h"
+#include "ace/OS_NS_errno.h"
+#include "ace/OS_NS_unistd.h"
+
+#if !defined(EC_DISABLE_OLD_EC)
+#include "EC_Scheduler_Info.h"
+#endif
+
+#if !defined (__ACE_INLINE__)
+#include "Driver.i"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID(EC_Tests, EC_Driver, "$Id$")
+
+EC_Driver::EC_Driver (void)
+ : n_consumers_ (1),
+ consumers_ (0),
+ n_suppliers_ (1),
+ suppliers_ (0),
+ tasks_ (0),
+ burst_count_ (100),
+ burst_size_ (100),
+ payload_size_ (0),
+ burst_pause_ (10000),
+ consumer_type_start_ (ACE_ES_EVENT_UNDEFINED),
+ consumer_type_count_ (1),
+ consumer_type_shift_ (2),
+ supplier_type_start_ (ACE_ES_EVENT_UNDEFINED),
+ supplier_type_count_ (1),
+ supplier_type_shift_ (2),
+ pid_file_name_ (0),
+ verbose_ (0),
+ thr_create_flags_ (THR_NEW_LWP|THR_BOUND|THR_SCHED_FIFO),
+ use_remote_ec_ (0),
+ event_service_name_ ("EventService"),
+ ec_impl_ (0)
+{
+ TAO_EC_Default_Factory::init_svcs ();
+}
+
+EC_Driver::~EC_Driver (void)
+{
+}
+
+int
+EC_Driver::run (int argc, char* argv[])
+{
+ ACE_TRY_NEW_ENV
+ {
+ // Calibrate the high resolution timer *before* starting the
+ // test.
+ ACE_High_Res_Timer::calibrate ();
+
+ this->run_init (argc, argv ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->execute_test (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->dump_results ();
+
+ this->run_cleanup (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "EC_Driver::run");
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR ((LM_ERROR, "EC_Driver (%P|%t) non-corba exception raised\n"));
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+void
+EC_Driver::run_init (int &argc, char* argv[]
+ ACE_ENV_ARG_DECL)
+{
+ this->initialize_orb_and_poa (argc, argv ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->parse_args (argc, argv))
+ ACE_THROW (CORBA::INTERNAL (TAO::VMCID,
+ CORBA::COMPLETED_NO));
+
+ if (this->verbose ())
+ this->print_args ();
+
+ if (this->pid_file_name_ != 0)
+ {
+ FILE* pid = ACE_OS::fopen (this->pid_file_name_, "w");
+ if (pid != 0)
+ {
+ ACE_OS::fprintf (pid, "%ld\n",
+ static_cast<long> (ACE_OS::getpid ()));
+ ACE_OS::fclose (pid);
+ }
+ }
+
+ if (this->move_to_rt_class () == -1)
+ ACE_THROW (CORBA::INTERNAL (TAO::VMCID,
+ CORBA::COMPLETED_NO));
+
+ this->initialize_ec_impl (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->allocate_consumers () == -1)
+ ACE_THROW (CORBA::NO_MEMORY (TAO::VMCID,
+ CORBA::COMPLETED_NO));
+
+ if (this->allocate_suppliers () == -1)
+ ACE_THROW (CORBA::NO_MEMORY (TAO::VMCID,
+ CORBA::COMPLETED_NO));
+
+ this->connect_clients (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+EC_Driver::run_cleanup (ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->disconnect_clients (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->shutdown_clients (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->destroy_ec (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Driver (%P|%t) channel destroyed\n"));
+
+ this->deactivate_ec (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Driver (%P|%t) channel deactivated\n"));
+
+ this->cleanup_tasks ();
+ this->cleanup_suppliers ();
+ this->cleanup_consumers ();
+ this->cleanup_ec ();
+
+ this->root_poa_->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ this->root_poa_ = PortableServer::POA::_nil ();
+
+ this->orb_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ this->orb_ = CORBA::ORB::_nil ();
+}
+
+void
+EC_Driver::initialize_orb_and_poa (int &argc, char* argv[]
+ ACE_ENV_ARG_DECL)
+{
+ this->orb_ =
+ CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ CORBA::Object_var poa_object =
+ this->orb_->resolve_initial_references("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (CORBA::is_nil (poa_object.in ()))
+ {
+ ACE_ERROR ((LM_ERROR,
+ "EC_Driver (%P|%t) Unable to initialize the POA.\n"));
+ return;
+ }
+
+ this->root_poa_ =
+ PortableServer::POA::_narrow (poa_object.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ PortableServer::POAManager_var poa_manager =
+ this->root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+EC_Driver::print_args (void) const
+{
+ ACE_DEBUG ((LM_DEBUG,
+ "Execution parameters:\n"
+ " consumers = <%d>\n"
+ " suppliers = <%d>\n"
+ " burst count = <%d>\n"
+ " burst size = <%d>\n"
+ " event size = <%d>\n"
+ " burst pause = <%d>\n"
+ " consumer type start = <%d>\n"
+ " consumer type count = <%d>\n"
+ " consumer type shift = <%d>\n"
+ " supplier type start = <%d>\n"
+ " supplier type count = <%d>\n"
+ " supplier type shift = <%d>\n"
+ " pid file name = <%s>\n",
+
+ this->n_consumers_,
+ this->n_suppliers_,
+ this->burst_count_,
+ this->burst_size_,
+ this->payload_size_,
+ this->burst_pause_,
+
+ this->consumer_type_start_,
+ this->consumer_type_count_,
+ this->consumer_type_shift_,
+ this->supplier_type_start_,
+ this->supplier_type_count_,
+ this->supplier_type_shift_,
+
+ this->pid_file_name_?this->pid_file_name_:"nil"
+ ) );
+}
+
+int
+EC_Driver::move_to_rt_class (void)
+{
+ int priority =
+ (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO)
+ + ACE_Sched_Params::priority_max (ACE_SCHED_FIFO)) / 2;
+ priority = ACE_Sched_Params::next_priority (ACE_SCHED_FIFO,
+ priority);
+ // Enable FIFO scheduling, e.g., RT scheduling class on Solaris.
+
+ if (ACE_OS::sched_params (ACE_Sched_Params (ACE_SCHED_FIFO,
+ priority,
+ ACE_SCOPE_PROCESS)) != 0)
+ {
+ if (ACE_OS::last_error () == EPERM)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "EC_Driver (%P|%t): user is not superuser, "
+ "so remain in time-sharing class\n"));
+ this->thr_create_flags_ = THR_NEW_LWP;
+ }
+ else
+ ACE_ERROR ((LM_ERROR,
+ "EC_Driver (%P|%t): sched_params failed\n"));
+ }
+
+ if (ACE_OS::thr_setprio (priority) == -1)
+ {
+ ACE_ERROR ((LM_ERROR, "EC_Driver (%P|%t) main thr_setprio failed,"
+ "no real-time features\n"));
+ }
+ return 0;
+}
+
+void
+EC_Driver::initialize_ec_impl (ACE_ENV_SINGLE_ARG_DECL)
+{
+#if !defined(EC_DISABLE_REMOTE_EC)
+ if (this->use_remote_ec_ == 1)
+ {
+ this->obtain_remote_ec (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ return;
+ }
+#endif
+
+ this->initialize_new_ec (ACE_ENV_SINGLE_ARG_PARAMETER);
+}
+
+#if !defined(EC_DISABLE_REMOTE_EC)
+void
+EC_Driver::obtain_remote_ec (ACE_ENV_SINGLE_ARG_DECL)
+{
+ CosNaming::NamingContext_var naming_context =
+ this->get_naming_context (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ CosNaming::Name channel_name (1);
+ channel_name.length (1);
+ channel_name[0].id = CORBA::string_dup (this->event_service_name_);
+
+ CORBA::Object_var tmp =
+ naming_context->resolve (channel_name ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->event_channel_ =
+ RtecEventChannelAdmin::EventChannel::_narrow (tmp.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+CosNaming::NamingContext_ptr
+EC_Driver::get_naming_context (ACE_ENV_SINGLE_ARG_DECL)
+{
+ CORBA::Object_var naming_obj =
+ this->orb_->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CosNaming::NamingContext::_nil ());
+
+ if (CORBA::is_nil (naming_obj.in ()))
+ ACE_ERROR ((LM_ERROR,
+ "EC_Driver (%P|%t) Unable to obtain the "
+ "Naming Service.\n"));
+
+ return CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER);
+}
+#endif
+
+void
+EC_Driver::initialize_new_ec (ACE_ENV_SINGLE_ARG_DECL)
+{
+ TAO_EC_Event_Channel_Attributes attr (this->root_poa_.in (),
+ this->root_poa_.in ());
+
+ this->modify_attributes (attr);
+
+ TAO_EC_Event_Channel *ec =
+ new TAO_EC_Event_Channel (attr);
+ this->ec_impl_ = ec;
+
+ ec->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->event_channel_ =
+ this->ec_impl_->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+EC_Driver::deactivate_ec (ACE_ENV_SINGLE_ARG_DECL)
+{
+#if !defined(EC_DISABLE_REMOTE_EC)
+ if (this->use_remote_ec_ == 1)
+ return;
+#endif
+
+ {
+ // Deactivate the EC
+ PortableServer::POA_var poa =
+ this->ec_impl_->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ PortableServer::ObjectId_var id =
+ poa->servant_to_id (this->ec_impl_ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ poa->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Driver (%P|%t) EC deactivated\n"));
+
+}
+
+void
+EC_Driver::destroy_ec (ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->event_channel_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+int
+EC_Driver::allocate_consumers (void)
+{
+ ACE_NEW_RETURN (this->consumers_,
+ EC_Consumer*[this->n_consumers_],
+ -1);
+ for (int i = 0; i < this->n_consumers_; ++i)
+ this->consumers_[i] =
+ this->allocate_consumer (i);
+ return 0;
+}
+
+int
+EC_Driver::allocate_suppliers (void)
+{
+ ACE_NEW_RETURN (this->suppliers_,
+ EC_Supplier*[this->n_suppliers_],
+ -1);
+ for (int i = 0; i < this->n_suppliers_; ++i)
+ this->suppliers_[i] =
+ this->allocate_supplier (i);
+ return 0;
+}
+
+EC_Consumer*
+EC_Driver::allocate_consumer (int i)
+{
+ return new EC_Consumer (this,
+ this->consumers_ + i);
+}
+
+EC_Supplier*
+EC_Driver::allocate_supplier (int i)
+{
+ return new EC_Supplier (this,
+ this->suppliers_ + i);
+}
+
+void
+EC_Driver::connect_clients (ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->connect_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->connect_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+EC_Driver::disconnect_clients (ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->disconnect_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->disconnect_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+EC_Driver::shutdown_clients (ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->shutdown_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->shutdown_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+EC_Driver::connect_consumers (ACE_ENV_SINGLE_ARG_DECL)
+{
+ RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
+ this->event_channel_->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ for (int i = 0; i < this->n_consumers_; ++i)
+ {
+ this->connect_consumer (consumer_admin.in (), i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Driver (%P|%t) connected consumer(s)\n"));
+}
+
+void
+EC_Driver::connect_consumer (
+ RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin,
+ int i
+ ACE_ENV_ARG_DECL)
+{
+ RtecEventChannelAdmin::ConsumerQOS qos;
+ int shutdown_event_type;
+ this->build_consumer_qos (i, qos, shutdown_event_type ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->consumers_[i]->connect (consumer_admin,
+ qos,
+ shutdown_event_type
+ ACE_ENV_ARG_PARAMETER);
+}
+
+void
+EC_Driver::build_consumer_qos (
+ int i,
+ RtecEventChannelAdmin::ConsumerQOS& qos,
+ int& shutdown_event_type
+ ACE_ENV_ARG_DECL_NOT_USED)
+{
+ RtecBase::handle_t rt_info = 0;
+
+ int type_start =
+ this->consumer_type_start_
+ + i * this->consumer_type_shift_;
+
+ shutdown_event_type = type_start + this->consumer_type_count_;
+
+ ACE_ConsumerQOS_Factory qos_factory;
+ qos_factory.start_disjunction_group (1 + this->consumer_type_count_);
+ qos_factory.insert_type (shutdown_event_type, rt_info);
+
+ for (int j = 0; j != this->consumer_type_count_; ++j)
+ qos_factory.insert_type (type_start + j, rt_info);
+
+ qos = qos_factory.get_ConsumerQOS ();
+}
+
+void
+EC_Driver::connect_suppliers (ACE_ENV_SINGLE_ARG_DECL)
+{
+ RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
+ this->event_channel_->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ for (int i = 0; i < this->n_suppliers_; ++i)
+ {
+ this->connect_supplier (supplier_admin.in (), i ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Driver (%P|%t) connected supplier(s)\n"));
+}
+
+void
+EC_Driver::connect_supplier (
+ RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin,
+ int i
+ ACE_ENV_ARG_DECL)
+{
+ RtecEventChannelAdmin::SupplierQOS qos;
+ int shutdown_event_type;
+ this->build_supplier_qos (i, qos, shutdown_event_type ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->suppliers_[i]->connect (supplier_admin,
+ qos,
+ shutdown_event_type
+ ACE_ENV_ARG_PARAMETER);
+}
+
+void
+EC_Driver::build_supplier_qos (
+ int i,
+ RtecEventChannelAdmin::SupplierQOS& qos,
+ int& shutdown_event_type
+ ACE_ENV_ARG_DECL_NOT_USED)
+{
+ int type_start = this->supplier_type_start_ + i*this->supplier_type_shift_;
+ int supplier_id = i + 1;
+ shutdown_event_type = type_start + this->supplier_type_count_;
+
+ RtecBase::handle_t rt_info = 0;
+
+ ACE_SupplierQOS_Factory qos_factory;
+ for (int j = 0; j != this->supplier_type_count_; ++j)
+ qos_factory.insert (supplier_id,
+ type_start + j,
+ rt_info, 1);
+
+ qos_factory.insert (supplier_id,
+ shutdown_event_type,
+ rt_info, 1);
+
+ qos = qos_factory.get_SupplierQOS ();
+}
+
+void
+EC_Driver::execute_test (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->allocate_tasks () == -1)
+ return;
+
+ this->activate_tasks (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Driver (%P|%t) suppliers are active\n"));
+
+ // Wait for the supplier threads...
+ if (ACE_Thread_Manager::instance ()->wait () == -1)
+ {
+ ACE_ERROR ((LM_ERROR, "EC_Driver (%P|%t) Thread_Manager wait failed\n"));
+ }
+
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Driver (%P|%t) suppliers finished\n"));
+}
+
+int
+EC_Driver::allocate_tasks (void)
+{
+ if (this->tasks_ != 0)
+ return 0;
+
+ ACE_NEW_RETURN (this->tasks_,
+ ACE_Task_Base*[this->n_suppliers_],
+ -1);
+
+ for (int i = 0; i < this->n_suppliers_; ++i)
+ this->tasks_[i] =
+ this->allocate_task (i);
+ return 0;
+}
+
+ACE_Task_Base*
+EC_Driver::allocate_task (int i)
+{
+ int start = this->supplier_type_start_ + i*this->supplier_type_shift_;
+ return new EC_Supplier_Task (this->suppliers_[i],
+ this,
+ this->suppliers_ + i,
+ this->burst_count_,
+ this->burst_size_,
+ this->burst_pause_,
+ this->payload_size_,
+ start + this->supplier_type_count_);
+}
+
+void
+EC_Driver::activate_tasks (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+{
+ int priority =
+ (ACE_Sched_Params::priority_min (ACE_SCHED_FIFO)
+ + ACE_Sched_Params::priority_max (ACE_SCHED_FIFO)) / 2;
+
+ if (ACE_BIT_DISABLED (this->thr_create_flags_, THR_SCHED_FIFO))
+ {
+ priority =
+ ACE_Sched_Params::priority_min (ACE_SCHED_OTHER);
+ }
+
+ for (int i = 0; i < this->n_suppliers_; ++i)
+ {
+ if (this->tasks_[i]->activate (this->thr_create_flags_,
+ 1, 0, priority) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "EC_Driver (%P|%t) Cannot activate thread "
+ "for supplier %d\n%p\n",
+ i, "EC_Driver - OS error is:"));
+ }
+ }
+}
+
+void
+EC_Driver::disconnect_suppliers (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->suppliers_ == 0)
+ return;
+ for (int i = 0; i < this->n_suppliers_; ++i)
+ {
+ this->suppliers_[i]->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Driver (%P|%t) suppliers disconnected\n"));
+}
+
+void
+EC_Driver::disconnect_consumers (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->consumers_ == 0)
+ return;
+ for (int i = 0; i < this->n_consumers_; ++i)
+ {
+ this->consumers_[i]->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Driver (%P|%t) consumers disconnected\n"));
+}
+
+void
+EC_Driver::shutdown_suppliers (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->suppliers_ == 0)
+ return;
+ for (int i = 0; i < this->n_suppliers_; ++i)
+ {
+ this->suppliers_[i]->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Driver (%P|%t) suppliers deactivated\n"));
+}
+
+void
+EC_Driver::shutdown_consumers (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->consumers_ == 0)
+ return;
+ for (int i = 0; i < this->n_consumers_; ++i)
+ {
+ this->consumers_[i]->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ if (this->verbose ())
+ ACE_DEBUG ((LM_DEBUG, "EC_Driver (%P|%t) consumers deactivated\n"));
+}
+
+void
+EC_Driver::dump_results (void)
+{
+ ACE_Throughput_Stats throughput;
+ ACE_UINT32 gsf = ACE_High_Res_Timer::global_scale_factor ();
+ char buf[BUFSIZ];
+ for (int j = 0; j < this->n_consumers_; ++j)
+ {
+ ACE_OS::sprintf (buf, "Consumer [%02d]", j);
+
+ this->consumers_[j]->dump_results (buf, gsf);
+ this->consumers_[j]->accumulate (throughput);
+ }
+ ACE_DEBUG ((LM_DEBUG, "\n"));
+
+ ACE_Throughput_Stats suppliers;
+ for (int i = 0; i < this->n_suppliers_; ++i)
+ {
+ ACE_OS::sprintf (buf, "Supplier [%02d]", i);
+
+ this->suppliers_[i]->dump_results (buf, gsf);
+ this->suppliers_[i]->accumulate (suppliers);
+ }
+
+ ACE_DEBUG ((LM_DEBUG, "\nTotals:\n"));
+ throughput.dump_results ("EC_Consumer/totals", gsf);
+
+ ACE_DEBUG ((LM_DEBUG, "\n"));
+ suppliers.dump_results ("EC_Supplier/totals", gsf);
+}
+
+int
+EC_Driver::parse_args (int &argc, char *argv [])
+{
+ ACE_Arg_Shifter arg_shifter (argc, argv);
+
+ while (arg_shifter.is_anything_left ())
+ {
+ const char *arg = arg_shifter.get_current ();
+
+ if (ACE_OS::strcmp (arg, "-verbose") == 0)
+ {
+ arg_shifter.consume_arg ();
+ this->verbose_ = 1;
+ }
+
+ else if (ACE_OS::strcmp (arg, "-remote") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ this->use_remote_ec_ = 1;
+ if (arg_shifter.is_parameter_next ())
+ {
+ this->event_service_name_ = arg_shifter.get_current ();
+ arg_shifter.consume_arg ();
+ }
+ }
+
+ else if (ACE_OS::strcmp (arg, "-suppliers") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ this->n_suppliers_ = ACE_OS::atoi (arg_shifter.get_current ());
+ arg_shifter.consume_arg ();
+ }
+ }
+
+ else if (ACE_OS::strcmp (arg, "-consumers") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ this->n_consumers_ = ACE_OS::atoi (arg_shifter.get_current ());
+ arg_shifter.consume_arg ();
+ }
+ }
+
+ else if (ACE_OS::strcmp (arg, "-burstcount") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ this->burst_count_ = ACE_OS::atoi (arg_shifter.get_current ());
+ arg_shifter.consume_arg ();
+ }
+ }
+
+ else if (ACE_OS::strcmp (arg, "-burstsize") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ this->burst_size_ = ACE_OS::atoi (arg_shifter.get_current ());
+ arg_shifter.consume_arg ();
+ }
+ }
+
+ else if (ACE_OS::strcmp (arg, "-payloadsize") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ this->payload_size_ = ACE_OS::atoi (arg_shifter.get_current ());
+ arg_shifter.consume_arg ();
+ }
+ }
+
+ else if (ACE_OS::strcmp (arg, "-burstpause") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ this->burst_pause_ = ACE_OS::atoi (arg_shifter.get_current ());
+ arg_shifter.consume_arg ();
+ }
+ }
+
+ else if (ACE_OS::strcmp (arg, "-consumer_tstart") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ this->consumer_type_start_ =
+ ACE_ES_EVENT_UNDEFINED
+ + ACE_OS::atoi (arg_shifter.get_current ());
+ arg_shifter.consume_arg ();
+ }
+ }
+
+ else if (ACE_OS::strcmp (arg, "-consumer_tcount") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ this->consumer_type_count_ =
+ ACE_OS::atoi (arg_shifter.get_current ());
+ arg_shifter.consume_arg ();
+ }
+ }
+
+ else if (ACE_OS::strcmp (arg, "-consumer_tshift") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ this->consumer_type_shift_ =
+ ACE_OS::atoi (arg_shifter.get_current ());
+ arg_shifter.consume_arg ();
+ }
+ }
+
+ else if (ACE_OS::strcmp (arg, "-supplier_tstart") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ this->supplier_type_start_ =
+ ACE_ES_EVENT_UNDEFINED
+ + ACE_OS::atoi (arg_shifter.get_current ());
+ arg_shifter.consume_arg ();
+ }
+ }
+
+ else if (ACE_OS::strcmp (arg, "-supplier_tcount") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ this->supplier_type_count_ =
+ ACE_OS::atoi (arg_shifter.get_current ());
+ arg_shifter.consume_arg ();
+ }
+ }
+
+ else if (ACE_OS::strcmp (arg, "-supplier_tshift") == 0)
+ {
+ arg_shifter.consume_arg ();
+
+ if (arg_shifter.is_parameter_next ())
+ {
+ this->supplier_type_shift_ =
+ ACE_OS::atoi (arg_shifter.get_current ());
+ arg_shifter.consume_arg ();
+ }
+ }
+
+ else
+ {
+ arg_shifter.ignore_arg ();
+ }
+
+ }
+ return 0;
+}
+
+void
+EC_Driver::print_usage (void)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ "EC_Driver Usage:\n"
+ " -verbose\n"
+ " -remote <ec_name>\n"
+ " -old_reactive\n"
+ " -old_threaded\n"
+ " -suppliers <nsuppliers>\n"
+ " -consumers <nsuppliers>\n"
+ " -burstcount <bursts>\n"
+ " -burstsize <size>\n"
+ " -payloadsize <size>\n"
+ " -burstpause <usecs>\n"
+ " -consumer_tstart <type>\n"
+ " -consumer_tcount <count>\n"
+ " -consumer_tshift <shift>\n"
+ " -supplier_tstart <type>\n"
+ " -supplier_tcount <count>\n"
+ " -supplier_tshift <shift>\n"
+ ));
+}
+
+void
+EC_Driver::modify_attributes (TAO_EC_Event_Channel_Attributes& attr)
+{
+ ACE_UNUSED_ARG(attr);
+
+ // This method can be overruled by derived tests to set the event channel
+ // attributes
+}
+
+void
+EC_Driver::cleanup_tasks (void)
+{
+ if (this->tasks_ != 0)
+ {
+ for (int i = 0; i != this->n_suppliers_; ++i)
+ {
+ delete this->tasks_[i];
+ this->tasks_[i] = 0;
+ }
+ delete[] this->tasks_;
+ this->tasks_ = 0;
+ }
+}
+
+void
+EC_Driver::cleanup_suppliers (void)
+{
+ if (this->suppliers_ != 0)
+ {
+ for (int i = 0; i != this->n_suppliers_; ++i)
+ {
+ delete this->suppliers_[i];
+ this->suppliers_[i] = 0;
+ }
+ delete[] this->suppliers_;
+ this->suppliers_ = 0;
+ }
+}
+
+void
+EC_Driver::cleanup_consumers (void)
+{
+ if (this->consumers_ != 0)
+ {
+ for (int i = 0; i != this->n_consumers_; ++i)
+ {
+ delete this->consumers_[i];
+ this->consumers_[i] = 0;
+ }
+ delete[] this->consumers_;
+ this->consumers_ = 0;
+ }
+}
+
+void
+EC_Driver::cleanup_ec (void)
+{
+ delete this->ec_impl_;
+#if !defined(EC_DISABLE_OLD_EC)
+ delete this->module_factory_;
+#endif
+}
+
+int
+EC_Driver::decode_consumer_cookie (void* cookie) const
+{
+ return static_cast<EC_Consumer**> (cookie) - this->consumers_;
+}
+
+int
+EC_Driver::decode_supplier_cookie (void* cookie) const
+{
+ return static_cast<EC_Supplier**> (cookie) - this->suppliers_;
+}
+
+void
+EC_Driver::consumer_push (void*,
+ const RtecEventComm::EventSet&
+ ACE_ENV_ARG_DECL_NOT_USED)
+{
+}
+
+void
+EC_Driver::consumer_shutdown (void*
+ ACE_ENV_ARG_DECL_NOT_USED)
+{
+}
+
+void
+EC_Driver::consumer_disconnect (void*
+ ACE_ENV_ARG_DECL_NOT_USED)
+{
+}
+
+void
+EC_Driver::supplier_disconnect (void*
+ ACE_ENV_ARG_DECL_NOT_USED)
+{
+}
diff --git a/TAO/orbsvcs/tests/Event/lib/Driver.h b/TAO/orbsvcs/tests/Event/lib/Driver.h
new file mode 100644
index 00000000000..31ac5df863e
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/lib/Driver.h
@@ -0,0 +1,329 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file Driver.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan (coryan@cs.wustl.edu)
+ */
+//=============================================================================
+
+
+#ifndef EC_DRIVER_H
+#define EC_DRIVER_H
+
+#include "ectest_export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "orbsvcs/RtecEventChannelAdminS.h"
+
+#include "ace/Stats.h"
+#include "ace/Task.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+class TAO_EC_Event_Channel_Attributes;
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+class TAO_Module_Factory;
+class EC_Consumer;
+class EC_Supplier;
+
+#define EC_DISABLE_REMOTE_EC
+#define EC_DISABLE_OLD_EC
+
+#if !defined(EC_DISABLE_REMOTE_EC)
+#include "orbsvcs/CosNamingC.h"
+#endif
+
+/**
+ * @class EC_Driver
+ *
+ * @brief Defines the interface of a test driver
+ *
+ * Abstract base class for the test driver, this let us implement a
+ * collocated and a non-collocated test, and to write generic
+ * consumers and suppliers that can call back the driver.
+ */
+class EC_Test_Export EC_Driver
+{
+public:
+ /// Constructor
+ EC_Driver (void);
+
+ /// Destructor
+ virtual ~EC_Driver (void);
+
+ /// Flag to indicate in the test should be verbose.
+ int verbose (void) const;
+
+ /// Execute the test.
+ virtual int run (int argc, char* argv[]);
+
+ /// The initialization section
+ virtual void run_init (int& argc, char* argv[]
+ ACE_ENV_ARG_DECL);
+
+ /// The cleanup section
+ virtual void run_cleanup (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Initialize the ORB and obtain the RootPOA object
+ virtual void initialize_orb_and_poa (int& argc, char* argv[]
+ ACE_ENV_ARG_DECL);
+
+ /// Parse the common command-line arguments for all tests
+ virtual int parse_args (int& argc, char* argv[]);
+
+ /// Print the usage method
+ virtual void print_usage (void);
+
+ /// Print out the arguments
+ virtual void print_args (void) const;
+
+ /// Run the test in the real-time class, return -1 on error.
+ virtual int move_to_rt_class (void);
+
+ /// Construct the EC and its helper objects, also activates the EC in
+ /// the RootPOA.
+ virtual void initialize_ec_impl (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// By default connect the consumers and then the suppliers, other
+ /// orders should work too.
+ virtual void connect_clients (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// By default disconnect the suppliers and then the consumers, other
+ /// orders should work too.
+ virtual void disconnect_clients (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// By default deactivate the suppliers and then the consumers, other
+ /// orders should work too.
+ virtual void shutdown_clients (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Connect all the consumers, by default it lets each consumer
+ /// connect itself.
+ virtual void connect_consumers (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Connect consumer number <i> using the consumer_admin provided.
+ virtual void connect_consumer (
+ RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin,
+ int i
+ ACE_ENV_ARG_DECL);
+
+ /// Build the QoS requirements for consumer <i>
+ virtual void build_consumer_qos (
+ int i,
+ RtecEventChannelAdmin::ConsumerQOS& qos,
+ int& shutdown_event_type
+ ACE_ENV_ARG_DECL_NOT_USED);
+
+ /// Connect all the suppliers, by default it lets each supplier
+ /// connect itself.
+ virtual void connect_suppliers (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Connect supplier number <i> using the supplier_admin provided.
+ virtual void connect_supplier (
+ RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin,
+ int i
+ ACE_ENV_ARG_DECL);
+
+ /// Build the QoS requirements for supplier <i>
+ virtual void build_supplier_qos (
+ int i,
+ RtecEventChannelAdmin::SupplierQOS& qos,
+ int& shutdown_event_type
+ ACE_ENV_ARG_DECL_NOT_USED);
+
+ /// Execute the test, by default simply call activate_suppliers()
+ virtual void execute_test (ACE_ENV_SINGLE_ARG_DECL);
+
+ /**
+ * Dump the results, i.e. invoke dump_results on all the suppliers
+ * and consumers, collect the latency and throughput results for
+ * each and print the totals too.
+ */
+ virtual void dump_results (void);
+
+ /// Disconnect all the consumers.
+ virtual void disconnect_consumers (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Disconnect all the suppliers.
+ virtual void disconnect_suppliers (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Deactivate all the consumers.
+ virtual void shutdown_consumers (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Deactivate all the suppliers.
+ virtual void shutdown_suppliers (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Call EC->destroy
+ virtual void destroy_ec (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// De-activate the EC (and its helper classes).
+ virtual void deactivate_ec (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Cleanup the resources
+ virtual void cleanup_ec (void);
+ virtual void cleanup_tasks (void);
+ virtual void cleanup_consumers (void);
+ virtual void cleanup_suppliers (void);
+
+ /// Allow modifications of the default EC attributes
+ virtual void modify_attributes (TAO_EC_Event_Channel_Attributes& attr);
+
+ /// Returns the index of the consumer for @a cookie
+ virtual int decode_consumer_cookie (void* cookie) const;
+
+ /// Returns the index of the supplier for @a cookie
+ virtual int decode_supplier_cookie (void* cookie) const;
+
+ /// One of the consumers in the test has received an event
+ virtual void consumer_push (void* consumer_cookie,
+ const RtecEventComm::EventSet& event
+ ACE_ENV_ARG_DECL);
+
+ /// One of the consumers has received a shutdown event
+ virtual void consumer_shutdown (void* consumer_cookie
+ ACE_ENV_ARG_DECL);
+
+ /// One of the consumers in the test has been disconnected from the EC
+ virtual void consumer_disconnect (void* consumer_cookie
+ ACE_ENV_ARG_DECL);
+
+ /// One of the suppliers in the test has been disconnected from the EC
+ virtual void supplier_disconnect (void* supplier_cookie
+ ACE_ENV_ARG_DECL);
+
+#if !defined(EC_DISABLE_REMOTE_EC)
+ /// Obtain the EC from the Naming service
+ virtual void obtain_remote_ec (ACE_ENV_SINGLE_ARG_DECL);
+
+ virtual CosNaming::NamingContext_ptr
+ get_naming_context (ACE_ENV_SINGLE_ARG_DECL);
+#endif
+
+ /// Initialize the EC using the new implementation
+ virtual void initialize_new_ec (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Allocate the suppliers and the consumers
+ virtual int allocate_consumers (void);
+ virtual int allocate_suppliers (void);
+
+ /// Allocate one consumer or supplier
+ virtual EC_Consumer* allocate_consumer (int i);
+ virtual EC_Supplier* allocate_supplier (int i);
+
+ /// Allocate one task for supplier number <i>
+ virtual int allocate_tasks (void);
+ virtual ACE_Task_Base* allocate_task (int i);
+
+ /// Activate all the tasks, by default runs each supplier on its
+ /// own thread.
+ virtual void activate_tasks (ACE_ENV_SINGLE_ARG_DECL);
+
+protected:
+ /// The ORB
+ CORBA::ORB_var orb_;
+
+ /// The Root POA
+ PortableServer::POA_var root_poa_;
+
+ /// The number of consumers
+ int n_consumers_;
+
+ /// The consumers
+ EC_Consumer** consumers_;
+
+ /// The number of suppliers
+ int n_suppliers_;
+
+ /// The suppliers
+ EC_Supplier** suppliers_;
+
+ /// The tasks for each supplier
+ ACE_Task_Base** tasks_;
+
+ /// How many bursts we will send from each supplier.
+ int burst_count_;
+
+ /// The number of events
+ int burst_size_;
+
+ /// The size of the payload on each event.
+ int payload_size_;
+
+ /// The time between each event burst, in microseconds.
+ int burst_pause_;
+
+ /**
+ * The consumers subscribe to different sets of events, as follows:
+ *
+ * Consumer0: [start , start + count)
+ * Consumer1: [start + 1*shift, start + 1*shift + count)
+ * Consumer2: [start + 2*shift, start + 2*shift + count)
+ * .....
+ * ....
+ * .
+ * Some sub-tests may choose other configurations, but this is good
+ * for many cases.
+ */
+ int consumer_type_start_;
+ int consumer_type_count_;
+ int consumer_type_shift_;
+
+ /**
+ * The suppliers generate different sets of events, as follows:
+ *
+ * Supplier0: [start , start + count)
+ * Supplier1: [start + 1*shift, start + 1*shift + count)
+ * Supplier2: [start + 2*shift, start + 2*shift + count)
+ * .....
+ * ....
+ * .
+ * Some sub-tests may choose other configurations, but this is good
+ * for many cases.
+ */
+ int supplier_type_start_;
+ int supplier_type_count_;
+ int supplier_type_shift_;
+
+ /// The name of a file where the process stores its pid
+ const char* pid_file_name_;
+
+ /// Verbosity flag
+ int verbose_;
+
+ /**
+ * The flags used to create threads, by default we attempt:
+ *
+ * THR_SCHED_FIFO|THR_BOUND|THR_NEW_LWP
+ *
+ * but if we don't have enough privileges we fall back to
+ *
+ * THR_NEW_LWP
+ *
+ */
+ int thr_create_flags_;
+
+ /// Use a remote event channel. If this flag is enabled it
+ /// superseedes any options for the event channel implementation.
+ int use_remote_ec_;
+
+ /// The name of the remote event service
+ const char* event_service_name_;
+
+ /// The event channel implementation
+ POA_RtecEventChannelAdmin::EventChannel *ec_impl_;
+
+ /// The event channel object reference
+ RtecEventChannelAdmin::EventChannel_var event_channel_;
+
+};
+
+#if defined (__ACE_INLINE__)
+#include "Driver.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* ECT_CONSUMER_H */
diff --git a/TAO/orbsvcs/tests/Event/lib/Driver.i b/TAO/orbsvcs/tests/Event/lib/Driver.i
new file mode 100644
index 00000000000..f346e7757c1
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/lib/Driver.i
@@ -0,0 +1,7 @@
+// $Id$
+
+ACE_INLINE int
+EC_Driver::verbose (void) const
+{
+ return this->verbose_;
+}
diff --git a/TAO/orbsvcs/tests/Event/lib/Event_lib.mpc b/TAO/orbsvcs/tests/Event/lib/Event_lib.mpc
new file mode 100644
index 00000000000..1e3ca37f7fb
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/lib/Event_lib.mpc
@@ -0,0 +1,10 @@
+// -*- MPC -*-
+// $Id$
+
+project(Event_Test_Lib): rtevent_serv, naming {
+ sharedname = ECTests
+ dynamicflags = EC_TEST_BUILD_DLL
+ Header_Files {
+ ectest_export.h
+ }
+}
diff --git a/TAO/orbsvcs/tests/Event/lib/Makefile.am b/TAO/orbsvcs/tests/Event/lib/Makefile.am
new file mode 100644
index 00000000000..af04cdea2c4
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/lib/Makefile.am
@@ -0,0 +1,58 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## ../bin/mwc.pl -type automake -noreldefs TAO.mwc
+
+ACE_BUILDDIR = $(top_builddir)/..
+ACE_ROOT = $(top_srcdir)/..
+TAO_BUILDDIR = $(top_builddir)
+TAO_ROOT = $(top_srcdir)
+
+
+## Makefile.Event_Test_Lib.am
+
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+
+noinst_LTLIBRARIES = libECTests.la
+
+libECTests_la_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -DEC_TEST_BUILD_DLL
+
+libECTests_la_SOURCES = \
+ Consumer.cpp \
+ Counting_Consumer.cpp \
+ Counting_Supplier.cpp \
+ Driver.cpp \
+ Supplier.cpp
+
+noinst_HEADERS = \
+ Consumer.h \
+ Counting_Consumer.h \
+ Counting_Supplier.h \
+ Driver.h \
+ Driver.i \
+ Supplier.h \
+ ectest_export.h
+
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/TAO/orbsvcs/tests/Event/lib/README b/TAO/orbsvcs/tests/Event/lib/README
new file mode 100644
index 00000000000..ead5bcaaacc
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/lib/README
@@ -0,0 +1,5 @@
+# $Id$
+
+This directory contains a small framework to write tests for the
+real-time event service. Check the Basic or Performance directories
+for examples of its use.
diff --git a/TAO/orbsvcs/tests/Event/lib/Supplier.cpp b/TAO/orbsvcs/tests/Event/lib/Supplier.cpp
new file mode 100644
index 00000000000..566a09d3c97
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/lib/Supplier.cpp
@@ -0,0 +1,298 @@
+// $Id$
+
+#include "Supplier.h"
+#include "orbsvcs/Time_Utilities.h"
+#include "orbsvcs/Event_Utilities.h"
+
+#include "tao/debug.h"
+#include "ace/OS_NS_unistd.h"
+
+ACE_RCSID (EC_Tests,
+ EC_Supplier,
+ "$Id$")
+
+EC_Supplier::EC_Supplier (EC_Driver *driver,
+ void* cookie)
+ : driver_ (driver),
+ cookie_ (cookie),
+ push_count_ (0),
+ burst_count_ (0),
+ burst_size_ (0),
+ payload_size_ (0),
+ burst_pause_ (0),
+ shutdown_event_type_ (0),
+ is_active_ (0)
+{
+}
+
+void
+EC_Supplier::send_event (int event_number
+ ACE_ENV_ARG_DECL)
+{
+ if (CORBA::is_nil (this->consumer_proxy_.in ()))
+ return;
+
+ // Create the event...
+
+ RtecEventComm::EventSet event (1);
+ event.length (1);
+
+ event[0].header.ttl = 1;
+
+ ACE_hrtime_t t = ACE_OS::gethrtime ();
+ ORBSVCS_Time::hrtime_to_TimeT (event[0].header.creation_time, t);
+
+ // We use replace to minimize the copies, this should result
+ // in just one memory allocation:
+ event[0].data.payload.length (this->payload_size_);
+
+ this->event_type (event_number, event[0]);
+
+ this->send_event (event ACE_ENV_ARG_PARAMETER);
+}
+
+void
+EC_Supplier::send_event (const RtecEventComm::EventSet& event
+ ACE_ENV_ARG_DECL)
+{
+ ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock_);
+
+ if (this->push_count_ == 0)
+ this->throughput_start_ = ACE_OS::gethrtime ();
+
+ this->push_count_ += event.length ();
+
+ if (TAO_debug_level > 0
+ && this->push_count_ % 100 == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "EC_Consumer (%P|%t): %d events received\n",
+ this->push_count_));
+ }
+
+ ACE_hrtime_t start = ACE_OS::gethrtime ();
+
+ this->consumer_proxy_->push (event ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ ACE_hrtime_t end = ACE_OS::gethrtime ();
+ this->throughput_.sample (end - this->throughput_start_,
+ end - start);
+}
+
+void
+EC_Supplier::event_type (int event_number,
+ RtecEventComm::Event &event)
+{
+ CORBA::ULong l = this->qos_.publications.length ();
+
+ if (l == 0)
+ {
+ event.header.source = 0;
+ event.header.type = this->shutdown_event_type_;
+ }
+ else
+ {
+ int i = event_number % l;
+ int type = this->qos_.publications[i].event.header.type;
+ if (type == this->shutdown_event_type_)
+ i = 0;
+
+ RtecEventComm::EventHeader& header =
+ this->qos_.publications[i].event.header;
+
+ event.header.source = header.source;
+ event.header.type = header.type;
+ }
+}
+
+void
+EC_Supplier::connect (RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin,
+ const RtecEventChannelAdmin::SupplierQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL)
+{
+ this->consumer_proxy_ =
+ supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->connect (qos, shutdown_event_type ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+EC_Supplier::connect (const RtecEventChannelAdmin::SupplierQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL)
+{
+ if (CORBA::is_nil (this->consumer_proxy_.in ()))
+ return; // @@ Throw?
+
+ this->qos_ = qos;
+ this->shutdown_event_type_ = shutdown_event_type;
+
+ if (CORBA::is_nil (this->myself_.in ()))
+ {
+ this->myself_ = this->_this (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ this->is_active_ = 1;
+
+ this->consumer_proxy_->connect_push_supplier (this->myself_.in (),
+ qos
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+EC_Supplier::disconnect (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (CORBA::is_nil (this->consumer_proxy_.in ()))
+ return;
+
+ this->consumer_proxy_->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->consumer_proxy_ =
+ RtecEventChannelAdmin::ProxyPushConsumer::_nil ();
+}
+
+void
+EC_Supplier::shutdown (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (!this->is_active_)
+ return;
+
+ // Deactivate the servant
+ PortableServer::POA_var poa =
+ this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+ PortableServer::ObjectId_var id =
+ poa->servant_to_id (this ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ poa->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ this->is_active_ = 0;
+ this->myself_ = RtecEventComm::PushSupplier::_nil ();
+}
+
+void
+EC_Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ this->driver_->supplier_disconnect (this->cookie_ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ this->consumer_proxy_ =
+ RtecEventChannelAdmin::ProxyPushConsumer::_nil ();
+}
+
+void
+EC_Supplier::dump_results (const char* name,
+ ACE_UINT32 gsf)
+{
+ this->throughput_.dump_results (name, gsf);
+}
+
+void
+EC_Supplier::accumulate (ACE_Throughput_Stats& stats) const
+{
+ stats.accumulate (this->throughput_);
+}
+
+// ****************************************************************
+
+EC_Supplier_Task::EC_Supplier_Task (EC_Supplier* supplier,
+ EC_Driver* driver,
+ void* cookie,
+ int burst_count,
+ int burst_size,
+ int burst_pause,
+ int payload_size,
+ int shutdown_event_type,
+ ACE_Thread_Manager* thr_mgr)
+ : ACE_Task_Base (thr_mgr),
+ supplier_ (supplier),
+ driver_ (driver),
+ cookie_ (cookie),
+ burst_count_ (burst_count),
+ burst_size_ (burst_size),
+ burst_pause_ (burst_pause),
+ payload_size_ (payload_size),
+ shutdown_event_type_ (shutdown_event_type)
+{
+}
+
+int
+EC_Supplier_Task::svc (void)
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+
+ // Initialize a time value to pace the test
+ ACE_Time_Value tv (0, this->burst_pause_);
+
+ RtecEventComm::EventSet event (1);
+ event.length (1);
+
+ event[0].header.ttl = 1;
+
+ ACE_hrtime_t t = ACE_OS::gethrtime ();
+ ORBSVCS_Time::hrtime_to_TimeT (event[0].header.creation_time, t);
+
+ // We use replace to minimize the copies, this should result
+ // in just one memory allocation;
+ event[0].data.payload.length (this->payload_size_);
+
+ for (int i = 0; i < this->burst_count_; ++i)
+ {
+ for (int j = 0; j < this->burst_size_; ++j)
+ {
+ ACE_TRY
+ {
+ this->supplier_->event_type (j, event[0]);
+
+ ACE_hrtime_t now = ACE_OS::gethrtime ();
+ ORBSVCS_Time::hrtime_to_TimeT (event[0].header.creation_time,
+ now);
+ // ACE_DEBUG ((LM_DEBUG, "(%t) supplier push event\n"));
+
+ this->supplier_->send_event (event ACE_ENV_ARG_PARAMETER);
+
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (CORBA::SystemException, sys_ex)
+ {
+ ACE_PRINT_EXCEPTION (sys_ex, "SYS_EX");
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "SYS_EX");
+ }
+ ACE_ENDTRY;
+ }
+ ACE_OS::sleep (tv);
+ }
+
+ ACE_TRY_EX(SHUTDOWN)
+ {
+ // Send one event shutdown from each supplier
+ event[0].header.type = this->shutdown_event_type_;
+ ACE_hrtime_t now = ACE_OS::gethrtime ();
+ ORBSVCS_Time::hrtime_to_TimeT (event[0].header.creation_time,
+ now);
+ this->supplier_->send_event (event ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK_EX (SHUTDOWN);
+ }
+ ACE_CATCH (CORBA::SystemException, sys_ex)
+ {
+ ACE_PRINT_EXCEPTION (sys_ex, "SYS_EX");
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "SYS_EX");
+ }
+ ACE_ENDTRY;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "Supplier task finished\n"));
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/Event/lib/Supplier.h b/TAO/orbsvcs/tests/Event/lib/Supplier.h
new file mode 100644
index 00000000000..065a20a15aa
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/lib/Supplier.h
@@ -0,0 +1,193 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file Supplier.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan (coryan@cs.wustl.edu)
+ */
+//=============================================================================
+
+
+#ifndef EC_SUPPLIER_H
+#define EC_SUPPLIER_H
+
+#include "Driver.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "orbsvcs/RtecEventCommS.h"
+#include "orbsvcs/RtecEventChannelAdminC.h"
+#include "ace/Task.h"
+#include "ace/OS_NS_time.h"
+
+/**
+ * @class EC_Supplier
+ *
+ * @brief Simple supplier object to implement EC tests.
+ *
+ * This class is a supplier of events.
+ * 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.
+ * The driver can request that to this class to send a new event,
+ * a new shutdown event or to become "active" and send a number of
+ * events at a certain rate.
+ */
+class EC_Test_Export EC_Supplier : public POA_RtecEventComm::PushSupplier
+{
+public:
+ /**
+ * Constructor, specifies the types of events to send.
+ * Notice that the user can connect to the EC using other
+ * publications, this is useful for filtering tests.
+ */
+ EC_Supplier (EC_Driver *driver,
+ void* supplier_cookie);
+
+ /// The types of the event is chosen by the driver, based on the
+ /// cookie and the <event_number>
+ void send_event (int event_number
+ ACE_ENV_ARG_DECL);
+
+ /// Send <event> to the EC.
+ void send_event (const RtecEventComm::EventSet& event
+ ACE_ENV_ARG_DECL);
+
+ /// Set the event type and source in <event>
+ void send_event (int event_number,
+ const RtecEventComm::Event& event);
+
+ /// Send a shutdown event.
+ void send_shutdown (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Connect using a <supplier_admin> and publications (<qos>)
+ /// computed by the user
+ virtual void connect (
+ RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin,
+ const RtecEventChannelAdmin::SupplierQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL);
+
+ /// Connect using the current consumer_proxy (useful for reconnect test)
+ virtual void connect (
+ const RtecEventChannelAdmin::SupplierQOS& qos,
+ int shutdown_event_type
+ ACE_ENV_ARG_DECL);
+
+ /// Disconnect from the EC, also deactivates the object
+ void disconnect (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Disconnect from the EC, also deactivates the object
+ void shutdown (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Dump the results...
+ virtual void dump_results (const char* name,
+ ACE_UINT32 global_scale_factor);
+
+ /// Add our statistics to <stats>
+ void accumulate (ACE_Throughput_Stats& stats) const;
+
+ /// Return an event type to push....
+ void event_type (int event_number,
+ RtecEventComm::Event& event);
+
+ // = The PushSupplier methods
+ virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+private:
+ /// Class we forward to.
+ EC_Driver *driver_;
+
+ /// Magic cookie provided by the supplier to identify ourselves
+ void* cookie_;
+
+ /// Protect the internal state
+ TAO_SYNCH_MUTEX lock_;
+
+ /// Count the number of push() calls
+ int push_count_;
+
+ /// We talk to the EC (as a supplier) using this proxy.
+ RtecEventChannelAdmin::ProxyPushConsumer_var consumer_proxy_;
+
+ /// The time for the first event sent
+ ACE_hrtime_t throughput_start_;
+
+ /// Measure the elapsed time spent while sending the events.
+ ACE_Throughput_Stats throughput_;
+
+ int burst_count_;
+ int burst_size_;
+ int payload_size_;
+ int burst_pause_;
+
+ /// The test data.
+ int shutdown_event_type_;
+
+ /// The publications, used to select the events.
+ RtecEventChannelAdmin::SupplierQOS qos_;
+
+ /// Is the supplier active in the POA?
+ int is_active_;
+
+ /// Cache the object reference to speed up connect/disconnect calls
+ RtecEventComm::PushSupplier_var myself_;
+};
+
+// ****************************************************************
+
+/**
+ * @class EC_Supplier_Task
+ */
+class EC_Supplier_Task : public ACE_Task_Base
+{
+public:
+ /// Constructor
+ EC_Supplier_Task (EC_Supplier* supplier,
+ EC_Driver* driver,
+ void* cookie,
+ int burst_count,
+ int burst_size,
+ int burst_pause,
+ int payload_size,
+ int shutdown_event_type,
+ ACE_Thread_Manager* thr_mgr = 0);
+
+ /// The svc call
+ virtual int svc (void);
+
+private:
+ /// The supplier
+ EC_Supplier* supplier_;
+
+ /// The driver program
+ EC_Driver* driver_;
+
+ /// The magic cookie assigned to the supplier
+ void* cookie_;
+
+ /// Number of events "bursts"
+ int burst_count_;
+
+ /// The number of events in a "burst", i.e. between two calls to
+ /// sleep.
+ int burst_size_;
+
+ /// The sleep time (in usecs) between each burst
+ int burst_pause_;
+
+ /// The size of the payload in each event.
+ int payload_size_;
+
+ /// Define the shutdown event, invoked at the end of the loop.
+ int shutdown_event_type_;
+};
+
+#endif /* EC_SUPPLIER_H */
diff --git a/TAO/orbsvcs/tests/Event/lib/ectest_export.h b/TAO/orbsvcs/tests/Event/lib/ectest_export.h
new file mode 100644
index 00000000000..a6e9712d496
--- /dev/null
+++ b/TAO/orbsvcs/tests/Event/lib/ectest_export.h
@@ -0,0 +1,40 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl
+// ------------------------------
+#ifndef EC_TEST_EXPORT_H
+#define EC_TEST_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (TAO_AS_STATIC_LIBS)
+# if !defined (EC_TEST_HAS_DLL)
+# define EC_TEST_HAS_DLL 0
+# endif /* ! EC_TEST_HAS_DLL */
+#else
+# if !defined (EC_TEST_HAS_DLL)
+# define EC_TEST_HAS_DLL 1
+# endif /* ! EC_TEST_HAS_DLL */
+#endif
+
+#if defined (EC_TEST_HAS_DLL) && (EC_TEST_HAS_DLL == 1)
+# if defined (EC_TEST_BUILD_DLL)
+# define EC_Test_Export ACE_Proper_Export_Flag
+# define EC_TEST_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define EC_TEST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* EC_TEST_BUILD_DLL */
+# define EC_Test_Export ACE_Proper_Import_Flag
+# define EC_TEST_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define EC_TEST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* EC_TEST_BUILD_DLL */
+#else /* EC_TEST_HAS_DLL == 1 */
+# define EC_Test_Export
+# define EC_TEST_SINGLETON_DECLARATION(T)
+# define EC_TEST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* EC_TEST_HAS_DLL == 1 */
+
+#endif /* EC_TEST_EXPORT_H */
+
+// End of auto generated file.