Exemple #1
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 *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;
}
Exemple #2
0
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;
}
Exemple #5
0
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 ());
}