diff options
author | William R. Otte <wotte@dre.vanderbilt.edu> | 2006-07-24 15:50:21 +0000 |
---|---|---|
committer | William R. Otte <wotte@dre.vanderbilt.edu> | 2006-07-24 15:50:21 +0000 |
commit | 3aff90f4a822fcf5d902bbfbcc9fa931d6191a8c (patch) | |
tree | 197c810e5f5bce17b1233a7cb8d7b50c0bcd25e2 /TAO/orbsvcs/tests/Event | |
parent | 6b846cf03c0bcbd8c276cb0af61a181e5f98eaae (diff) | |
download | ATCD-3aff90f4a822fcf5d902bbfbcc9fa931d6191a8c.tar.gz |
Repo restructuring
Diffstat (limited to 'TAO/orbsvcs/tests/Event')
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. |