int ACE_TMAIN (int argc, ACE_TCHAR *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 ACE_TCHAR *ecname = ACE_TEXT ("EventService"); const ACE_TCHAR *address = ACE_TEXT ("localhost"); const ACE_TCHAR *iorfile = 0; u_short port = 12345; u_short listenport = 12345; int mcast = 1; for (int i = 0; argv[i] != 0; i++) { if (ACE_OS::strcasecmp(argv[i], ACE_TEXT ("-ecname")) == 0) { if (argv[i+1] != 0) ecname = argv[++i]; else ACE_ERROR_RETURN ((LM_ERROR, "Missing Event channel name\n"),0); } else if (ACE_OS::strcasecmp(argv[i], ACE_TEXT ("-address")) == 0) { if (argv[i+1] != 0) address = argv[++i]; else ACE_ERROR_RETURN ((LM_ERROR, "Missing address\n"),0); } else if (ACE_OS::strcasecmp(argv[i], ACE_TEXT ("-port")) == 0) { if (argv[i+1] != 0) port = ACE_OS::atoi(argv[++i]); else ACE_ERROR_RETURN ((LM_ERROR, "Missing port\n"),0); } else if (ACE_OS::strcasecmp(argv[i], ACE_TEXT ("-listenport")) == 0) { if (argv[i+1] != 0) listenport = ACE_OS::atoi(argv[++i]); else ACE_ERROR_RETURN ((LM_ERROR, "Missing port\n"), 0); } else if (ACE_OS::strcasecmp(argv[i], ACE_TEXT ("-iorfile")) == 0) { if (argv[i+1] != 0) iorfile = argv[++i]; else ACE_ERROR_RETURN ((LM_ERROR, "Missing ior file\n"), 0); } else if (ACE_OS::strcasecmp(argv[i], ACE_TEXT ("-udp")) == 0) mcast = 0; } // Get the POA CORBA::Object_var tmpobj = orb->resolve_initial_references ("RootPOA"); PortableServer::POA_var poa = PortableServer::POA::_narrow (tmpobj.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); tmpobj = poa->id_to_reference(oid.in()); RtecEventChannelAdmin::EventChannel_var ec = RtecEventChannelAdmin::EventChannel::_narrow(tmpobj.in()); // Find the Naming Service. tmpobj = orb->resolve_initial_references("NameService"); CosNaming::NamingContextExt_var root_context = CosNaming::NamingContextExt::_narrow(tmpobj.in()); // Bind the Event Channel using Naming Services CosNaming::Name_var name = root_context->to_name (ACE_TEXT_ALWAYS_CHAR (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); tmpobj = poa->id_to_reference(oid.in()); RtecEventComm::PushSupplier_var supplier = RtecEventComm::PushSupplier::_narrow(tmpobj.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 only if // one is not otherwise available via the naming service. ACE_INET_Addr send_addr (port, address); SimpleAddressServer addr_srv_impl (send_addr); // Create an instance of the addr server for local use PortableServer::ObjectId_var addr_srv_oid = poa->activate_object(&addr_srv_impl); tmpobj = poa->id_to_reference(addr_srv_oid.in()); RtecUDPAdmin::AddrServer_var addr_srv = RtecUDPAdmin::AddrServer::_narrow(tmpobj.in()); // Create and initialize the sender object PortableServer::Servant_var<TAO_ECG_UDP_Sender> sender = TAO_ECG_UDP_Sender::create(); TAO_ECG_UDP_Out_Endpoint endpoint; // need to be explicit about the address type when built with // IPv6 support, otherwise SOCK_DGram::open defaults to ipv6 when // given a sap_any address. This causes trouble on at least solaris // and windows, or at most on not-linux. if (endpoint.dgram ().open (ACE_Addr::sap_any, send_addr.get_type()) == -1) { ACE_ERROR_RETURN ((LM_ERROR, "Cannot open send endpoint\n"), 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_Refcounted_Endpoint clone (new TAO_ECG_UDP_Out_Endpoint (endpoint)); 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 PortableServer::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. TAO_ECG_Refcounted_Endpoint clone2 (new TAO_ECG_UDP_Out_Endpoint (endpoint)); receiver->init (ec.in (), clone2, 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()); //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) ACE_ERROR ((LM_ERROR,"Cannot open EH\n")); ACE_auto_ptr_reset(eh,udp_eh.release()); //eh.reset(udp_eh.release()); } // Create an event (just a string in this case). // 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; #if !defined (TAO_LACKS_EVENT_CHANNEL_ANY) // Initialize data fields in event. const CORBA::String_var eventData = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR (ecname)); event[0].data.any_value <<= eventData; #else // Use the octet sequence payload instead char *tmpstr = const_cast<char *>(ACE_TEXT_ALWAYS_CHAR (ecname)); size_t len = ACE_OS::strlen(tmpstr) +1; event[0].data.payload.replace ( len, len, reinterpret_cast<CORBA::Octet *> (tmpstr)); #endif /* !TAO_LACKS_EVENT_CHANNEL_ANY */ if (iorfile != 0) { CORBA::String_var str = orb->object_to_string( ec.in() ); std::ofstream iorFile( ACE_TEXT_ALWAYS_CHAR(iorfile) ); iorFile << str.in() << std::endl; iorFile.close(); } ACE_DEBUG ((LM_DEBUG, "Starting main loop\n")); const int EVENT_DELAY_MS = 1000; while (1) { consumer->push (event); ACE_Time_Value tv(0, 1000 * EVENT_DELAY_MS); orb->run(tv); } orb->destroy(); return 0; } catch (const CORBA::Exception& exc) { ACE_ERROR ((LM_ERROR, "Caught CORBA::Exception\n%C (%C)\n", exc._name (), exc._rep_id () )); } return 1; }
int ACE_TMAIN(int argc, ACE_TCHAR *argv[]) { TAO_EC_Default_Factory::init_svcs (); try { // ORB initialization boiler plate... CORBA::ORB_var orb = CORBA::ORB_init (argc, argv); if (parse_args (argc, argv) == -1) { ACE_ERROR ((LM_ERROR, "Usage: Service [-o IOR_file_name]\n")); return 1; } CORBA::Object_var object = orb->resolve_initial_references ("RootPOA"); PortableServer::POA_var poa = PortableServer::POA::_narrow (object.in ()); PortableServer::POAManager_var poa_manager = poa->the_POAManager (); poa_manager->activate (); // **************************************************************** #if 0 // Obtain a reference to the naming service... CORBA::Object_var naming_obj = orb->resolve_initial_references ("NameService"); CosNaming::NamingContext_var naming_context = CosNaming::NamingContext::_narrow (naming_obj.in ()); #endif /* 0 */ // **************************************************************** // Create an scheduling service POA_RtecScheduler::Scheduler* sched_impl = 0; if (config_run) { ACE_NEW_RETURN (sched_impl, RECONFIG_SCHED_TYPE, 1); } else { ACE_NEW_RETURN (sched_impl, RECONFIG_SCHED_TYPE (configs_size, configs, infos_size, infos, 0, 0, 0), 1); } RtecScheduler::Scheduler_var scheduler = sched_impl->_this (); #if 0 // Bind the scheduler with the naming service so clients // (consumers and suppliers) can resolve it, some (old) // implementations of the EC will try to do the same thing // (yikes!) CosNaming::Name schedule_name (1); schedule_name.length (1); schedule_name[0].id = CORBA::string_dup ("ScheduleService"); // Register the servant with the Naming Context.... naming_context->rebind (schedule_name, scheduler.in ()); #endif /* 0 */ // **************************************************************** TAO_EC_Event_Channel_Attributes attributes (poa.in (), poa.in ()); attributes.scheduler = scheduler.in (); // no need to dup TAO_EC_Event_Channel ec_impl (attributes); ACE_DEBUG ((LM_DEBUG, "activating EC\n")); ec_impl.activate (); ACE_DEBUG ((LM_DEBUG, "EC activated\n")); RtecEventChannelAdmin::EventChannel_var event_channel = ec_impl._this (); // **************************************************************** // Create a consumer, intialize its RT_Info structures, and // connnect to the event channel.... Consumer consumer_impl; RtecScheduler::handle_t consumer_rt_info1 = scheduler->create ("consumer_event_1"); // Let's say that the execution time for event 1 is 2 // milliseconds... ACE_Time_Value tv (0, 2000); TimeBase::TimeT time; ORBSVCS_Time::Time_Value_to_TimeT (time, tv); scheduler->set (consumer_rt_info1, RtecScheduler::VERY_HIGH_CRITICALITY, time, time, time, 0, RtecScheduler::VERY_LOW_IMPORTANCE, time, 0, RtecScheduler::OPERATION); RtecScheduler::handle_t consumer_rt_info2 = scheduler->create ("consumer_event_2"); // Let's say that the execution time for event 2 is 1 // milliseconds... tv.set (0, 1000); ORBSVCS_Time::Time_Value_to_TimeT (time, tv); scheduler->set (consumer_rt_info2, RtecScheduler::VERY_LOW_CRITICALITY, time, time, time, 0, RtecScheduler::VERY_LOW_IMPORTANCE, time, 0, RtecScheduler::OPERATION); 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_type (ACE_ES_EVENT_UNDEFINED, consumer_rt_info1); consumer_qos.insert_type (ACE_ES_EVENT_UNDEFINED + 1, consumer_rt_info2); // The canonical protocol to connect to the EC RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin = event_channel->for_consumers (); RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy = consumer_admin->obtain_push_supplier (); RtecEventComm::PushConsumer_var consumer = consumer_impl._this (); ACE_DEBUG ((LM_DEBUG, "connecting consumer\n")); supplier_proxy->connect_push_consumer (consumer.in (), consumer_qos.get_ConsumerQOS ()); ACE_DEBUG ((LM_DEBUG, "consumer connected\n")); // **************************************************************** Supplier supplier_impl; RtecScheduler::handle_t supplier_rt_info1 = scheduler->create ("supplier_event_1"); // 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, 10000); TimeBase::TimeT tmp; ORBSVCS_Time::Time_Value_to_TimeT (tmp, tv); RtecScheduler::Period_t rate = ACE_U64_TO_U32(tmp); scheduler->set (supplier_rt_info1, RtecScheduler::VERY_HIGH_CRITICALITY, 0, 0, 0, rate, RtecScheduler::VERY_LOW_IMPORTANCE, 0, 1, RtecScheduler::OPERATION); RtecScheduler::handle_t supplier_rt_info2 = scheduler->create ("supplier_event_2"); // 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, 20000); ORBSVCS_Time::Time_Value_to_TimeT (tmp, tv); rate = ACE_U64_TO_U32(tmp); scheduler->set (supplier_rt_info2, RtecScheduler::VERY_HIGH_CRITICALITY, 0, 0, 0, rate, RtecScheduler::VERY_LOW_IMPORTANCE, 0, 1, RtecScheduler::OPERATION); RtecEventComm::EventSourceID supplier_id = 1; ACE_SupplierQOS_Factory supplier_qos; supplier_qos.insert (supplier_id, ACE_ES_EVENT_UNDEFINED, supplier_rt_info1, 1 /* number of calls, but what does that mean? */); supplier_qos.insert (supplier_id, ACE_ES_EVENT_UNDEFINED + 1, supplier_rt_info2, 1 /* number of calls, but what does that mean? */); // The canonical protocol to connect to the EC RtecEventChannelAdmin::SupplierAdmin_var supplier_admin = event_channel->for_suppliers (); RtecEventChannelAdmin::ProxyPushConsumer_var consumer_proxy = supplier_admin->obtain_push_consumer (); RtecEventComm::PushSupplier_var supplier = supplier_impl._this (); ACE_DEBUG ((LM_DEBUG, "connecting supplier\n")); consumer_proxy->connect_push_supplier (supplier.in (), supplier_qos.get_SupplierQOS ()); ACE_DEBUG ((LM_DEBUG, "supplier connected\n")); // **************************************************************** // At this point the consumer and supplier are connected to the // EC, they have provided their QoS info to the Scheduling // Service and the EC has informed the Scheduler about the // dependencies between them. // We can now compute the schedule for this configuration... // The schedule is returned in this variables.... if (config_run) { ACE_DEBUG ((LM_DEBUG, "Computing schedule\n")); RtecScheduler::RT_Info_Set_var infos; RtecScheduler::Dependency_Set_var deps; RtecScheduler::Config_Info_Set_var configs; RtecScheduler::Scheduling_Anomaly_Set_var anomalies; // Obtain the range of valid priorities in the current // platform, the scheduler hard-code this values in the // generated file, but in the future we may just use the // "logical" priorities and define the mapping to OS // priorities at run-time. int min_os_priority = ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, ACE_SCOPE_THREAD); int max_os_priority = ACE_Sched_Params::priority_max (ACE_SCHED_FIFO, ACE_SCOPE_THREAD); scheduler->compute_scheduling (min_os_priority, max_os_priority, infos.out (), deps.out (), configs.out (), anomalies.out ()); // Dump the schedule to a file.. ACE_Scheduler_Factory::dump_schedule (infos.in (), deps.in (), configs.in (), anomalies.in (), ACE_TEXT("schedule.out")); } // **************************************************************** ACE_DEBUG ((LM_DEBUG, "Pushing events\n")); // Generate a few events.... RtecEventComm::EventSet event1 (1); event1.length (1); event1[0].header.type = ACE_ES_EVENT_UNDEFINED; event1[0].header.source = supplier_id; event1[0].header.ttl = 1; RtecEventComm::EventSet event2 (1); event2.length (1); event2[0].header.type = ACE_ES_EVENT_UNDEFINED + 1; event2[0].header.source = supplier_id; event2[0].header.ttl = 1; for (int i = 0; i != 200; ++i) { if (i % 2 == 0) { consumer_proxy->push (event1); } else { consumer_proxy->push (event2); } ACE_Time_Value rate (0, 10000); ACE_OS::sleep (rate); } // **************************************************************** // We should do a lot of cleanup (disconnect from the EC, // deactivate all the objects with the POA, etc.) but this is // just a simple demo so we are going to be lazy. } catch (const CORBA::Exception& ex) { ex._tao_print_exception ("Service"); return 1; } return 0; }
int ACE_TMAIN (int argc, ACE_TCHAR *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 ACE_TCHAR* ecname = ACE_TEXT ("EventService"); const ACE_TCHAR* remote_ecname = 0; const ACE_TCHAR* iorfile = 0; for (int i = 0; argv[i] != 0; i++) { if (ACE_OS::strcmp(argv[i], ACE_TEXT("-ecname")) == 0) { if (argv[i+1] != 0) { i++; ecname = argv[i]; } else { std::cerr << "Missing Event channel name" << std::endl; } } if (ACE_OS::strcmp(argv[i], ACE_TEXT("-gateway")) == 0) { if (argv[i+1] != 0) { i++; remote_ecname = argv[i]; } else { std::cerr << "Missing Event channel name" << std::endl; } } if (ACE_OS::strcmp(argv[i], ACE_TEXT("-iorfile")) == 0) { if (argv[i+1] != 0) { i++; iorfile = argv[i]; } } } // 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 (); // Spawn a thread for the orb ACE_Thread_Manager *thread_mgr = ACE_Thread_Manager::instance(); thread_mgr->spawn(orb_thread, orb.in()); // Create a local event channel and register it with the RootPOA. TAO_EC_Event_Channel_Attributes attributes (poa.in (), poa.in ()); PortableServer::Servant_var<TAO_EC_Event_Channel> ec_impl = new TAO_EC_Event_Channel(attributes); ec_impl->activate (); PortableServer::ObjectId_var oid = poa->activate_object(ec_impl.in()); 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. object = orb->resolve_initial_references("NameService"); CosNaming::NamingContextExt_var root_context = CosNaming::NamingContextExt::_narrow(object.in()); CosNaming::Name_var name = root_context->to_name (ACE_TEXT_ALWAYS_CHAR (ecname)); root_context->rebind(name.in(), ec.in()); // Get a SupplierAdmin object from the EventChannel. RtecEventChannelAdmin::SupplierAdmin_var admin = ec->for_suppliers(); // Get a ProxyPushConsumer from the SupplierAdmin. RtecEventChannelAdmin::ProxyPushConsumer_var consumer = admin->obtain_push_consumer(); // Instantiate an EchoEventSupplier_i servant. PortableServer::Servant_var<EchoEventSupplier_i> servant = new EchoEventSupplier_i(orb.in()); // Register it with the RootPOA. oid = poa->activate_object(servant.in()); CORBA::Object_var supplier_obj = poa->id_to_reference(oid.in()); RtecEventComm::PushSupplier_var supplier = RtecEventComm::PushSupplier::_narrow(supplier_obj.in()); // Publish the events the supplier provides. ACE_SupplierQOS_Factory qos; qos.insert (MY_SOURCE_ID, // Supplier's unique id MY_EVENT_TYPE, // Event type 0, // handle to the rt_info structure 1); // number of calls // Connect as a supplier of the published events. consumer->connect_push_supplier (supplier.in (), qos.get_SupplierQOS ()); // Create an event (just a string in this case). const CORBA::String_var eventData = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR (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; PortableServer::Servant_var<TAO_EC_Gateway_IIOP> gateway = new TAO_EC_Gateway_IIOP; int gateway_initialized = 0; std::cout << "Supplier starting sending of events.\n"; while (1) { consumer->push (event); ACE_Time_Value tv(0, 1000 * EVENT_DELAY_MS); orb->run(tv); if ((remote_ecname != 0) && (!gateway_initialized)) { try { // Get the remote event channel object CORBA::Object_var obj = root_context->resolve_str (ACE_TEXT_ALWAYS_CHAR (remote_ecname)); RtecEventChannelAdmin::EventChannel_var remote_ec = RtecEventChannelAdmin::EventChannel::_narrow(obj.in()); int ok = 0; if (!CORBA::is_nil(remote_ec.in())) { // Now check if we can talk to it... try { RtecEventChannelAdmin::SupplierAdmin_var adm = remote_ec->for_suppliers(); ok = 1; } catch(const CORBA::UserException&) { // What is the correct exception(s) to catch here? } } // There is a good remote event channel so initialize the // gateway. if (ok) { gateway->init(remote_ec.in(), ec.in()); PortableServer::ObjectId_var gateway_oid = poa->activate_object(gateway.in()); CORBA::Object_var gateway_obj = poa->id_to_reference(gateway_oid.in()); RtecEventChannelAdmin::Observer_var obs = RtecEventChannelAdmin::Observer::_narrow(gateway_obj.in()); RtecEventChannelAdmin::Observer_Handle local_ec_obs_handle = ec->append_observer (obs.in ()); ACE_UNUSED_ARG (local_ec_obs_handle); gateway_initialized = 1; std::cout << "Gateway initialized\n"; if (iorfile != 0) { CORBA::String_var str = orb->object_to_string( ec.in() ); std::ofstream iorFile( ACE_TEXT_ALWAYS_CHAR(iorfile) ); iorFile << str.in() << std::endl; iorFile.close(); } } } catch(const CosNaming::NamingContext::NotFound&) { // Try again later... } } } orb->destroy(); return 0; } catch(const CORBA::Exception& exc) { std::cerr << "Caught CORBA::Exception" << std::endl << exc << std::endl; } return 1; }
int ACE_TMAIN (int argc, ACE_TCHAR *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 ACE_TCHAR* ecname = ACE_TEXT ("EventService"); const ACE_TCHAR* address = ACE_TEXT ("localhost"); const ACE_TCHAR* iorfile = 0; u_short port = 12345; u_short listenport = 12345; int mcast = 1; for (int i = 0; argv[i] != 0; i++) { if (ACE_OS::strcmp(argv[i], ACE_TEXT("-ecname")) == 0) { if (argv[i+1] != 0) { i++; ecname = argv[i]; } else { std::cerr << "Missing Event channel name" << std::endl; } } else if (ACE_OS::strcmp(argv[i], ACE_TEXT("-address")) == 0) { if (argv[i+1] != 0) { i++; address = argv[i]; } else { std::cerr << "Missing address" << std::endl; } } else if (ACE_OS::strcmp(argv[i], ACE_TEXT("-port")) == 0) { if (argv[i+1] != 0) { i++; port = ACE_OS::atoi(argv[i]); } else { std::cerr << "Missing port" << std::endl; } } else if (ACE_OS::strcmp(argv[i], ACE_TEXT("-listenport")) == 0) { if (argv[i+1] != 0) { i++; listenport = ACE_OS::atoi(argv[i]); } else { std::cerr << "Missing port" << std::endl; } } else if (ACE_OS::strcmp(argv[i], ACE_TEXT("-iorfile")) == 0) { if (argv[i+1] != 0) { i++; iorfile = argv[i]; } } else if (ACE_OS::strcmp(argv[i], ACE_TEXT("-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 ()); PortableServer::Servant_var<TAO_EC_Event_Channel> ec_impl = new TAO_EC_Event_Channel(attributes); ec_impl->activate (); PortableServer::ObjectId_var oid = poa->activate_object(ec_impl.in()); 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 (ACE_TEXT_ALWAYS_CHAR (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. PortableServer::Servant_var<EchoEventSupplier_i> servant = new EchoEventSupplier_i(orb.in()); // Register it with the RootPOA. oid = poa->activate_object(servant.in()); 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); PortableServer::Servant_var<SimpleAddressServer> addr_srv_impl = new SimpleAddressServer(send_addr); PortableServer::ObjectId_var addr_srv_oid = poa->activate_object(addr_srv_impl.in()); 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 PortableServer::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_Refcounted_Endpoint clone (new TAO_ECG_UDP_Out_Endpoint (endpoint)); 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 PortableServer::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. TAO_ECG_Refcounted_Endpoint clone2 (new TAO_ECG_UDP_Out_Endpoint (endpoint)); receiver->init (ec.in (), clone2, 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()); //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()); //eh.reset(udp_eh.release()); } // Create an event (just a string in this case). const CORBA::String_var eventData = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR (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( ACE_TEXT_ALWAYS_CHAR(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(const CORBA::Exception& exc) { std::cerr << "Caught CORBA::Exception" << std::endl << exc << std::endl; } return 1; }
void Test_Supplier::connect (RtecScheduler::Scheduler_ptr scheduler, const char* name, int burst_count, int burst_size, int event_size, int burst_pause, int type_start, int type_count, RtecEventChannelAdmin::EventChannel_ptr ec) { this->burst_count_ = burst_count; this->burst_size_ = burst_size; this->event_size_ = event_size; this->burst_pause_ = burst_pause; this->type_start_ = type_start; this->type_count_ = type_count; RtecScheduler::handle_t rt_info = scheduler->create (name); ACE_Time_Value tv (0, 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); scheduler->set (rt_info, RtecScheduler::VERY_HIGH_CRITICALITY, time, time, time, rate, RtecScheduler::VERY_LOW_IMPORTANCE, time, 1, RtecScheduler::OPERATION); this->supplier_id_ = ACE::crc32 (name); ACE_DEBUG ((LM_DEBUG, "ID for <%s> is %04.4x\n", name, this->supplier_id_)); ACE_SupplierQOS_Factory qos; for (int i = 0; i != type_count; ++i) { qos.insert (this->supplier_id_, type_start + i, rt_info, 1); } qos.insert (this->supplier_id_, ACE_ES_EVENT_SHUTDOWN, rt_info, 1); RtecEventChannelAdmin::SupplierAdmin_var supplier_admin = ec->for_suppliers (); this->consumer_proxy_ = supplier_admin->obtain_push_consumer (); RtecEventComm::PushSupplier_var objref = this->supplier_._this (); this->consumer_proxy_->connect_push_supplier (objref.in (), qos.get_SupplierQOS ()); }