Esempio n. 1
0
void
Test_Consumer::connect (RtecScheduler::Scheduler_ptr scheduler,
                        const char* name,
                        int type_start,
                        int type_count,
                        RtecEventChannelAdmin::EventChannel_ptr ec)
{
  RtecScheduler::handle_t rt_info =
    scheduler->create (name);

  // 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);
  scheduler->set (rt_info,
                  RtecScheduler::VERY_HIGH_CRITICALITY,
                  time, time, time,
                  0,
                  RtecScheduler::VERY_LOW_IMPORTANCE,
                  time,
                  0,
                  RtecScheduler::OPERATION);

  ACE_ConsumerQOS_Factory qos;
  qos.start_disjunction_group ();
  qos.insert_type (ACE_ES_EVENT_SHUTDOWN, rt_info);
  for (int i = 0; i != type_count; ++i)
    {
      qos.insert_type (type_start + i, rt_info);
    }

  // = Connect as a consumer.
  RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
    ec->for_consumers ();

  this->supplier_proxy_ =
    consumer_admin->obtain_push_supplier ();

  RtecEventComm::PushConsumer_var objref = this->_this ();

  this->supplier_proxy_->connect_push_consumer (objref.in (),
                                                qos.get_ConsumerQOS ());
}
Esempio n. 2
0
void
TAO_EC_ProxyPushSupplier::push_nocopy (RtecEventComm::EventSet& event,
                                       TAO_EC_QOS_Info& qos_info)
{
  // The mutex is already held by the caller (usually the filter()
  // method)
  if (!this->is_connected_i ())
    return; // TAO_THROW (RtecEventComm::Disconnected ());????

  if (this->suspended_)
    return;

  TAO_ESF_RefCount_Guard<CORBA::ULong> ace_mon (this->refcount_);
  // The guard will decrement the reference count, notice that the
  // reference count can become 0, but this is not the right spot to
  // check for that and destroy the object.
  // If we did so then we would destroy the object, and consequently
  // the mutex, but the mutex is used later when the stack unwinds and
  // the filter() method tries to destroy the mutex (that originally
  // acquired the mutex in the first place).
  // So the correct thing to do is to just decrement the reference
  // count and let the filter() method do the destruction.

  RtecEventComm::PushConsumer_var consumer =
    RtecEventComm::PushConsumer::_duplicate (this->consumer_.in ());

  this->pre_dispatch_hook (event);

  {
    TAO_EC_Unlock reverse_lock (*this->lock_);

    ACE_GUARD_THROW_EX (TAO_EC_Unlock, ace_mon, reverse_lock,
                        RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ());

    this->event_channel_->dispatching ()->push_nocopy (this,
                                                       consumer.in (),
                                                       event,
                                                       qos_info);
  }

  if (this->child_ != 0)
    this->child_->clear ();
}
void
TAO_EC_Default_ProxyPushSupplier::disconnect_push_supplier ()
{
  RtecEventComm::PushConsumer_var consumer;
  int connected = 0;

  {
    ACE_GUARD_THROW_EX (
        ACE_Lock, ace_mon, *this->lock_,
        CORBA::INTERNAL ());
    // @@ RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ());

    connected = this->is_connected_i ();
    consumer = this->consumer_._retn ();

    if (connected)
      this->cleanup_i ();
  }

  // Notify the event channel....
  this->event_channel_->disconnected (this);

  if (!connected)
    {
      return;
    }

  if (this->event_channel_->disconnect_callbacks ())
    {
      try
        {
          consumer->disconnect_push_consumer ();
        }
      catch (const CORBA::Exception& ex)
        {
          // Ignore exceptions, we must isolate other clients from
          // problems on this one.
          ex._tao_print_exception ("ProxySupplier::disconnect_push_supplier");
        }
    }
}
Esempio n. 4
0
int
Consumer::run (int argc, ACE_TCHAR* argv[])
{
  try
    {
      // ORB initialization boiler plate...
      CORBA::ORB_var orb =
        CORBA::ORB_init (argc, argv);

      // Do *NOT* make a copy because we don't want the ORB to outlive
      // the run() method.
      this->orb_ = orb.in ();

      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 ();

      // Obtain the event channel from the naming service
      CORBA::Object_var naming_obj =
        orb->resolve_initial_references ("NameService");

      if (CORBA::is_nil (naming_obj.in ()))
        ACE_ERROR_RETURN ((LM_ERROR,
                           " (%P|%t) Unable to get the Naming Service.\n"),
                          1);

      CosNaming::NamingContext_var naming_context =
        CosNaming::NamingContext::_narrow (naming_obj.in ());

      CosNaming::Name name (1);
      name.length (1);
      name[0].id = CORBA::string_dup ("EventService");

      CORBA::Object_var ec_obj =
        naming_context->resolve (name);

      RtecEventChannelAdmin::EventChannel_var event_channel =
        RtecEventChannelAdmin::EventChannel::_narrow (ec_obj.in ());

      // The canonical protocol to connect to the EC
      RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
        event_channel->for_consumers ();

      RtecEventChannelAdmin::ProxyPushSupplier_var supplier =
        consumer_admin->obtain_push_supplier ();

      RtecEventComm::PushConsumer_var consumer =
        this->_this ();

      // Simple subscription, but usually the helper classes in
      // $TAO_ROOT/orbsvcs/Event_Utils.h are a better way to do this.
      RtecEventChannelAdmin::ConsumerQOS qos;
      qos.dependencies.length (2);
      RtecEventComm::EventHeader& h0 =
        qos.dependencies[0].event.header;
      h0.type   = ACE_ES_DISJUNCTION_DESIGNATOR;
      h0.source = ACE_ES_EVENT_SOURCE_ANY;

      RtecEventComm::EventHeader& h1 =
        qos.dependencies[1].event.header;
      h1.type   = ACE_ES_EVENT_UNDEFINED; // first free event type
      h1.source = ACE_ES_EVENT_SOURCE_ANY;

      supplier->connect_push_consumer (consumer.in (), qos);

      // Wait for events, using work_pending()/perform_work() may help
      // or using another thread, this example is too simple for that.
      orb->run ();

      // We don't do any cleanup, it is hard to do it after shutdown,
      // and would complicate the example; plus it is almost
      // impossible to do cleanup after ORB->run() because the POA is
      // in the holding state.  Applications should use
      // work_pending()/perform_work() to do more interesting stuff.
      // Check the supplier for the proper way to do cleanup.
    }
  catch (const CORBA::Exception& ex)
    {
      ex._tao_print_exception ("Consumer::run");
      return 1;
    }
  return 0;
}
Esempio n. 5
0
int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
  try
  {
    // Initialize the ORB.
    CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

    const ACE_TCHAR *ecname = ACE_TEXT ("EventService");
    for (int i = 0; argv[i] != 0; i++) {
      if (ACE_OS::strcmp(argv[i], ACE_TEXT("-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 (ACE_TEXT_ALWAYS_CHAR (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 and register it
    // with the RootPOA
    PortableServer::Servant_var<EchoEventConsumer_i> servant =
      new EchoEventConsumer_i(orb.in(), supplier.in(), EVENT_LIMIT);
    PortableServer::ObjectId_var oid = poa->activate_object(servant.in());
    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.
    orb->destroy();

    std::cout << "Test completed." << std::endl;

    return 0;
  }
  catch(const CORBA::Exception& exc)
  {
    std::cerr << "Caught CORBA::Exception" << std::endl << exc << std::endl;
  }
  return 1;
}
Esempio n. 6
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;
}
Esempio n. 7
0
int
Consumer::run (int argc, ACE_TCHAR* argv[])
{
  try
    {
      // First parse our command line options
      if (this->parse_args(argc, argv) != 0)
      {
         return -1;
      }

      // ORB initialization boiler plate...
      CORBA::ORB_var orb =
        CORBA::ORB_init (argc, argv);

      // Do *NOT* make a copy because we don't want the ORB to outlive
      // the run() method.
      this->orb_ = orb.in ();

      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 ();

      // Obtain the event channel from the naming service
      CORBA::Object_var naming_obj =
        orb->resolve_initial_references ("NameService");

      if (CORBA::is_nil (naming_obj.in ()))
        ACE_ERROR_RETURN ((LM_ERROR,
                           " (%P|%t) Unable to get the Naming Service.\n"),
                          1);

      CosNaming::NamingContext_var naming_context =
        CosNaming::NamingContext::_narrow (naming_obj.in ());

      CosNaming::Name name (1);
      name.length (1);
      name[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR(ecname));

      CORBA::Object_var ec_obj =
        naming_context->resolve (name);

      RtecEventChannelAdmin::EventChannel_var event_channel =
        RtecEventChannelAdmin::EventChannel::_narrow (ec_obj.in ());

      if (CORBA::is_nil (event_channel.in ()))
        ACE_ERROR_RETURN ((LM_ERROR,
                           " (%P|%t) Unable to get Event Channel.\n"),
                          1);

      // The canonical protocol to connect to the EC
      RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
        event_channel->for_consumers ();

      RtecEventChannelAdmin::ProxyPushSupplier_var supplier =
        consumer_admin->obtain_push_supplier ();

      RtecEventComm::PushConsumer_var consumer =
        this->_this ();

      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
      for (int i = 0; i < 10; i++)
        {
          qos.insert (MY_SOURCE_ID  + i,   // Source ID
                      MY_EVENT_TYPE + i,  // Event Type
                      0);             // handle to the rt_info
        }
      supplier->connect_push_consumer (consumer.in (), qos);

      // Wait for events, using work_pending()/perform_work() may help
      // or using another thread, this example is too simple for that.
      orb->run ();

      // We don't do any cleanup, it is hard to do it after shutdown,
      // and would complicate the example; plus it is almost
      // impossible to do cleanup after ORB->run() because the POA is
      // in the holding state.  Applications should use
      // work_pending()/perform_work() to do more interesting stuff.
      // Check the supplier for the proper way to do cleanup.
    }
  catch (const CORBA::Exception& ex)
    {
      ex._tao_print_exception ("Consumer::run");
      return 1;
    }
  return 0;
}
Esempio n. 8
0
int
ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
  try
    {
      // Initialize ORB and POA, POA Manager, parse args.
      CORBA::ORB_var orb =
        CORBA::ORB_init (argc, argv);

      if (parse_args (argc, argv) == -1)
        return 1;

      CORBA::Object_var obj =
        orb->resolve_initial_references ("RootPOA");
      PortableServer::POA_var poa =
        PortableServer::POA::_narrow (obj.in ());
      if (check_for_nil (poa.in (), "POA") == -1)
        return 1;

      PortableServer::POAManager_var manager =
        poa->the_POAManager ();

      // Obtain reference to EC.
      obj = orb->resolve_initial_references ("Event_Service");
      RtecEventChannelAdmin::EventChannel_var ec =
        RtecEventChannelAdmin::EventChannel::_narrow (obj.in ());
      if (check_for_nil (ec.in (), "EC") == -1)
        return 1;

      // Create the consumer and register it with POA.
      PortableServer::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);
      consumer_deactivator.disallow_deactivation ();

      // Obtain reference to ConsumerAdmin.
      RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
        ec->for_consumers ();

      // Obtain ProxyPushSupplier and connect this consumer.
      RtecEventChannelAdmin::ProxyPushSupplier_var supplier =
        consumer_admin->obtain_push_supplier ();

      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 ());

      // Allow processing of CORBA requests.
      manager->activate ();

      // Receive events from EC.
      orb->run ();
    }
  catch (const CORBA::Exception& ex)
    {
      ex._tao_print_exception ("Exception in Consumer:");
      return 1;
    }

  return 0;
}
Esempio n. 9
0
int
Consumer::run (int argc, ACE_TCHAR* argv[])
{
  try
    {
      // ORB initialization boiler plate...
      CORBA::ORB_var orb =
        CORBA::ORB_init (argc, argv);

      // Do *NOT* make a copy because we don't want the ORB to outlive
      // the run() method.
      this->orb_ = orb.in ();
/*
      if (argc <= 1)
        {
          ACE_ERROR ((LM_ERROR,
                      "Usage: Consumer <event_channel_ior>\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 ();

      // Obtain the event channel, we could use a naming service, a
      // command line argument or resolve_initial_references(), but
      // this is simpler...
/*      object =
        orb->string_to_object (argv[1]);

      RtecEventChannelAdmin::EventChannel_var event_channel =
        RtecEventChannelAdmin::EventChannel::_narrow (object.in ());
*/

     // Obtain the event channel
      CORBA::Object_var naming_obj =
        this->orb_->resolve_initial_references (NAMING_SERVICE_NAME);

      // Need to check return value for errors.
      if (CORBA::is_nil (naming_obj.in ()))
        throw CORBA::UNKNOWN ();

      this->naming_context_ =
        CosNaming::NamingContext::_narrow (naming_obj.in ());

      CosNaming::Name name (1);
      name.length (1);
      name[0].id = CORBA::string_dup (EVENT_TLS_LOG_FACTORY_NAME);

      CORBA::Object_var obj =
        this->naming_context_->resolve (name);

      this->event_log_factory_ =
        RTEventLogAdmin::EventLogFactory::_narrow (obj.in ());


      // The canonical protocol to connect to the EC

      this->supplier_ =
        this->event_log_factory_->obtain_push_supplier ();

      RtecEventComm::PushConsumer_var consumer =
        this->_this ();

      // Simple subscription, but usually the helper classes in
      // $TAO_ROOT/orbsvcs/Event_Utils.h are a better way to do this.
      RtecEventChannelAdmin::ConsumerQOS qos;
      qos.dependencies.length (2);
      RtecEventComm::EventHeader& h0 =
        qos.dependencies[0].event.header;
      h0.type   = ACE_ES_DISJUNCTION_DESIGNATOR;
      h0.source = ACE_ES_EVENT_SOURCE_ANY;

      RtecEventComm::EventHeader& h1 =
        qos.dependencies[1].event.header;
      h1.type   = ACE_ES_EVENT_UNDEFINED; // first free event type
      h1.source = ACE_ES_EVENT_SOURCE_ANY;

      this->supplier_->connect_push_consumer (consumer.in (), qos);

      // Wait for events, using work_pending()/perform_work() may help
      // or using another thread, this example is too simple for that.
      orb->run ();

      // We don't do any cleanup, it is hard to do it after shutdown,
      // and would complicate the example; plus it is almost
      // impossible to do cleanup after ORB->run() because the POA is
      // in the holding state.  Applications should use
      // work_pending()/perform_work() to do more interesting stuff.
      // Check the supplier for the proper way to do cleanup.
    }
  catch (const CORBA::Exception& ex)
    {
      ex._tao_print_exception ("Consumer::run");
      return 1;
    }
  return 0;
}