summaryrefslogtreecommitdiff
path: root/TAO/docs/events_tutorial.html
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/docs/events_tutorial.html')
-rw-r--r--TAO/docs/events_tutorial.html1819
1 files changed, 0 insertions, 1819 deletions
diff --git a/TAO/docs/events_tutorial.html b/TAO/docs/events_tutorial.html
deleted file mode 100644
index c07ae139d88..00000000000
--- a/TAO/docs/events_tutorial.html
+++ /dev/null
@@ -1,1819 +0,0 @@
-<html>
-<head>
-<title>Using the Real-Time Event Service</title>
-</head>
-
-<BODY text = "#000000"
-link="#000fff"
-vlink="#ff0f0f"
-bgcolor="#ffffff">
-
-<br>
-<br>
-
-<center>
-<h1>Using the Real-Time Event Service</h1><P>
-
-<A HREF="http://www.cs.wustl.edu/~cdgill/">Chris Gill</a>,
-<A HREF="http://www.cs.wustl.edu/~harrison/">Tim Harrison</a>, and
-<A HREF="http://www.cs.wustl.edu/~coryan/">Carlos O'Ryan</a><br><br>
-
-<A HREF="mailto:cdgill@cs.wustl.edu">cdgill@cs.wustl.edu</a>,
-<A HREF="mailto:harrison@cs.wustl.edu">harrison@cs.wustl.edu</a>, and
-<A HREF="mailto:coryan@cs.wustl.edu">coryan@cs.wustl.edu</a><br>
-</center>
-
-<br>
-<br>
-
-<P><HR><P>
-<!-- ************************************************************ -->
-
-<center>
-<table cellpadding=10 border=0 cellspacing=4>
-<tr><td>
-<h2><a name="Section0">Overview</a></h2>
-<BR>
-<BR>
-<tr><td>
-<h3>Contents</h3>
-<BR>
-<ol>
- <li> <a href="events_tutorial.html#Section0">Overview</a>
- <li> <a href="events_tutorial.html#Section1">The COS Event Model</a>
- <li> <a href="events_tutorial.html#Section2">Real-Time Event Service Enhancements</a>
- <li> <a href="events_tutorial.html#Section3">The Real-Time Event Service</a>
- <li> <a href="events_tutorial.html#Section4">Developing Consumers</a>
- <li> <a href="events_tutorial.html#Section5">Developing Suppliers</a>
- <li> <a href="events_tutorial.html#Section6">Caring For Your Event Channel</a>
- <li> <a href="events_tutorial.html#Section7">Sample Applications</a>
- <li> <a href="events_tutorial.html#Section8">Reference Materials</a>
-</ol>
-
-<P><HR><P>
-<tr><td>
-<h3>Introduction</h3>
-<BR>
-This material is intended to provide an introduction to the COS Event Model,
-the Real-Time extensions to that model in TAO, and a set of examples that
-illustrate the techniques used to build systems using these models. The CORBA
-Event Service provides a flexible model for asynchronous communication among
-objects. However, the standard CORBAEvent Service specification lacks
-important features required by real-time applications. These features include
-event filtering, event correlation, and periodic event processing.<P>
-
-The standard CORBA operation invocation model supports twoway, oneway,
-and deferred synchronous interactions between clients and servers.
-The primary strength of the twoway model is its intuitive mapping onto
-the <code>object->operation()</code> paradigm supported by OO languages.
-In principle, twoway invocations simplify the development of
-distributed applications by supporting an implicit request/response
-protocol that makes remote operation invocations transparent to the
-client. <P>
-
-In practice, however, the standard CORBA operation invocation models
-are too restrictive for real-time applications. In particular, these
-models lack asynchronous message delivery, do not support timed
-invocations or group communication, and can lead to excessive polling
-by clients. Moreover, standard oneway invocations might not implement
-reliable delivery and deferred synchronous invocations require the use
-of the CORBA Dynamic Invocation Interface (DII), which yields
-<A HREF="http://www.cs.wustl.edu/~schmidt/GLOBECOM-96.ps.gz">excessive
-overhead</A> for most real-time applications. <P>
-
-The Event Service is a CORBA Object Service (COS) that is designed to
-alleviate some of the restrictions with standard CORBA invocation
-models. In particular, the COS Event Service supports asynchronous
-message delivery and allows one or more suppliers to send messages to
-one or more consumers. Event data can be delivered from suppliers to
-consumers without requiring these participants to know about each
-other explicitly. <P>
-
-There are two models (<EM>i.e.</EM>, <EM>push</EM> vs. <EM>pull</EM>)
-of participant collaborations in the COS Event Service architecture.
-This material focuses on real-time enhancements to the push model, which
-allows suppliers of events to initiate the transfer of event data to
-consumers. Suppliers push events to the Event Channel, which in turn
-pushes the events to consumers. <P>
-
-Suppliers use Event Channels to push data to consumers. Likewise,
-consumers can explicitly pull data from suppliers. The push and pull
-semantics of event propagation help to free consumers and suppliers
-from the overly restrictive synchronous semantics of the standard
-CORBA twoway communication model. In addition, Event Channels can
-implement group communication by serving as a replicator, broadcaster,
-or multicaster that forward events from one or more suppliers to
-multiple consumers.<p>
-
-</table>
-</center>
-
-<hr><P>
-<!-- ************************************************************ -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<tr><td align=center>
-<center><h2><a name="Section1">The COS Event Model</a></h2></center>
-</table></center>
-
-<table cellpadding=1 border=0 cellspacing=4>
-<h3>Relationships Between Modules</h3>
-
-The role of each component in the COS Event Model is outlined
-below:<P>
-
-<ul>
- <li> <b><i>EventChannel</i></b> -- The EventChannel interface provides
- two factory methods, which allow applications to obtain consumer and
- supplier administration objects, respectively, and use them to create
- the other objects described below, to connect to the event channel. <P>
-
- <li> <b><i>SupplierAdmin</i></b> -- The SupplierAdmin interface provides
- factory methods which create the appropriate supplier proxy objects. <P>
-
- <li> <b><i>ConsumerAdmin</i></b> -- The ConsumerAdmin interface provides
- factory methods which create the appropriate consumer proxy objects. <P>
-
- <li> <b><i>ProxyPullSupplier</i></b> -- The ProxyPullSupplier
- interface is used by consumers in the pull model to connect and
- disconnect from the channel. This interface inherits from the
- PullSupplier interface, and acts as a proxy for the suppliers
- from which the channel will pull events. <P>
-
- <li> <b><i>ProxyPushSupplier</i></b> -- The ProxyPushSupplier
- interface is used by consumers in the push model to connect and
- disconnect from the channel. This interface inherits from the
- PushSupplier interface, and acts as a proxy for the suppliers
- which will push events to the channel. <P>
-
- <li> <b><i>ProxyPullConsumer</i></b> -- The ProxyPullConsumer
- interface is used by suppliers in the pull model to connect and
- disconnect from the channel. This interface inherits from the
- PullConsumer interface, and acts as a proxy for the consumers
- on whose behalf the channel will pull events. <P>
-
- <li> <b><i>ProxyPushConsumer</i></b> -- The ProxyPushConsumer
- interface is used by suppliers in the push model to connect and
- disconnect from the channel. This interface inherits from the
- PushConsumer interface, and acts as a proxy for the consumers
- to which the channel will push events. <P>
-
- <li> <b><i>PullSupplier</i></b> -- The PullSupplier interface provides
- the necessary methods of a supplier of events in the pull model. <P>
-
- <li> <b><i>PushSupplier</i></b> -- The PushSupplier interface provides
- the necessary methods of a supplier of events in the push model. <P>
-
- <li> <b><i>PullConsumer</i></b> -- The PullConsumer interface provides
- the necessary methods of a consumer of events in the pull model. <P>
-
- <li> <b><i>PushConsumer</i></b> -- The PushConsumer interface provides
- the necessary methods of a consumer of events in the push model. <P>
-</ul>
-
-<tr><td>
-</table>
-<br>
-<br>
-<center><table cellpadding=1 border=0 cellspacing=4>
-<tr><td align=center>
-<center><IMG SRC="http://www.cs.wustl.edu/~schmidt/gifs/ec_participants2.gif"></center>
-</table></center>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<h3>The Push Model</h3>
-<tr><td>
-<center><IMG SRC="http://www.cs.wustl.edu/~schmidt/gifs/ec_push.gif"></center>
-
-<tr><td>
-<UL>
- <LI> Consumers - Ultimate targets of events
- <LI> Suppliers - Generate events
- <LI> Event Channel - Decouple consumers and suppliers by propagating
- events to consumers on behalf of suppliers
-</UL>
-</table></center>
-
-<P><HR><P>
-<!-- ************************************************************ -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<tr><td>
-
-<h2><a name="Section2">Real-Time Event Service Enhancements</a></h2>
-
-<tr><td>
-<ul>
- <li> <b><i>Prioritized dispatching within preemption
- classes</i></b> -- The current implementation can dispatch
- events in the same queue by their order of importance, which is
- necessary to support priorities within a rate group. <p>
-
- <li> <b><i>Suspend/resume</i></b> -- If a consumer's event
- dependencies change at run-time, it can utilize the
- suspend/resume functionality through the new
- <code>ProxyPushSupplier::suspend</code> and
- <code>ProxyPushSupplier::resume</code> methods. When a
- consumer invokes <code>ProxyPushSupplier::suspend</code>, the
- dependencies registered with that proxy will be disabled until
- the <code>resume</code> methods is called. These enhancements
- allow run-time flexibility of event dependencies, but maintains
- the determinism required by the system scheduling policy (i.e.,
- consumers can not add and remove dependencies at run-time -
- just suspend and resume them).<p>
-
- <LI> <B><I>Event data model</I></B> -- The data model may use
- unions, untyped buffers, or type anys.<P>
-
-<LI> <B><I>Event filtering</I></B> -- Consumers may register for
-events based on event type, or supplier id. The event channel filters events
-based on these registrations, to ensure efficient event delivery.<P>
-
-<LI> <B><I>Event correlation</I></B> -- Consumers may register
-for event delivery based on conjunctive or disjunctive sets of events. Conjunctive
-registrations cause the event channel to notify the consumer when <I>all</I>
-events in the set have arrived. Disjunctive registrations cause the event channel
-to notify the consumer when <I>any</I> event in the set has arrived.<P>
-
-<LI> <B><I>Periodic event processing</I></B> -- Consumers
-may register for suppliers based on timed events. Periodic suppliers push events
-into the channel at well defined intervals.<P>
-
- <LI> <B><I>Active consumers and suppliers</I></B> -- See
- <a href="events_tutorial.html#Section3">The Real-Time Event Service</a><P>.
-
-</ul>
-</table>
-</center>
-
-<P><HR><P>
-<!-- ************************************************************ -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<tr><td align=center>
-<h2><a name="Section3">The Real-Time Event Service</a></h2>
-</table></center>
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<h3>Real-Time ORB and Services</h3>
-<tr><td>
-<center><IMG SRC="http://www.cs.wustl.edu/~schmidt/gifs/corbaopt10.gif"></center>
-
-<br>
-<center><tr><td>
-<ul>
- <li> Real-time event dispatching<P>
- <UL>
- <LI> Priority-based queueing and preemption mechanisms<P>
- </UL>
- <li> Centralized event filtering and correlation<P>
- <ul>
- <LI> Source/type-based filtering<P>
- <LI> Conjunction/Disjunction (AND/OR) correlations<P>
- </ul>
-
- <li> Periodic and Aperiodic processing <P>
- <UL>
- <LI> Canonical timeouts<P>
- <LI> Dependency timeouts
- </UL>
-</ul>
-</center>
-</table></center>
-<br>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<tr><td align=center>
-<h3>Real-Time Event Service Internals</h3>
-<BR>
-<tr><td>
-<center><IMG SRC="http://www.cs.wustl.edu/~schmidt/gifs/ec_dispatching.gif"></center>
-</table></center>
-<br>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<h3>Characteristics of Real-Time Push Event Service Participants</h3>
-
-<tr><td>
-Two major roles are played by the participants in a real-time push event
-service.<P>
-
-<tr><td>
-The first role is that of an event consumer, which receives events from the
-event channel. A consumer specifies the type and/or source id for each event
-it is interested in receiving.<P>
-
-In hard real-time applications, a consumer must also specify RT_Info data for
-each event it is interested in receiving, and any other events on which that
-event depends. The RT_Info structure resides in the Scheduler, and is
-accessed through the scheduler interface. A unique handle is returned to the
-consumer when an RT_Info is created, which can then be used to set the
-information in the RT_Info. An RT_Info handle may also be obtained via the
-Scheduler's lookup method.<P>
-
-<tr><td>
-The second role is that of an event supplier, which generates events and
-passes them into the event channel. A supplier must specify its source id,
-and the type of each event it will generate.
-
-<tr><td>
-In hard real-time applications, a supplier must also specify RT_Info data for
-the events it will generate. In particular, it must specify the maximum rate
-at which it will generate each event. This information is used by a real-time
-scheduler to assign appropriate dispatch priorities.<P>
-
-<tr><td>
-Note that the event channel may also be configured to use a null scheduling service. This will
-cause all operations to be dispatched at the same priority, and will not require the application
-to specify worst case execution times, periods, etc.
-
-<tr><td>
-The consumer and supplier roles may be combined, as illustrated in the tables below. There are
-two main cases in which the roles are combined: a passive one termed Consumer/Supplier which
-borrows a thread of execution to produce events, and an active one termed Supplier/Consumer
-which produces events in its own thread. Both consume events and produce events.<P>
-</table></center>
-
-<br>
-<br>
-<center><table cellpadding=4 border=1 cellspacing=4>
-<h4>EC Roles and Specified RT_Info Contents</h4>
-
-<tr>
-<th>EC Roles
-<th>RT_Info Contents
-<th>Domain Examples
-</tr>
-
-<tr>
-<td> Consumer
-<td> dependencies (and optionally, importance)
-<td> Display, Exception & Maintenance Logs
-</tr>
-
-<tr>
-<td> Consumer/Supplier
-<td> dependencies (and optionally, importance)
-<td> Navigation Component (NAV)
-</tr>
-
-<tr>
-<td> Supplier/Consumer
-<td> rate, dependencies (and optionally, importance)
-<td> Kalman Filter
-</tr>
-
-<tr>
-<td> Supplier
-<td> rate
-<td> Operator Control Panel, EC Reactor Threads
-</tr>
-
-</table></center>
-<BR>
-<BR>
-
-
-<center><table cellpadding=1 border=1 cellspacing=4>
-<h4>EC Roles and Scheduler Dependency Chain</h4>
-
-<tr>
-<th> EC Roles
-<th> Scheduler Dependency Chain
-</tr>
-
-<tr>
-<td> Pure Consumer
-<td> root node
-</tr>
-
-<tr>
-<td> Consumer/Supplier
-<td> internal node
-</tr>
-
-<tr>
-<td> Supplier/Consumer
-<td> internal node
-</tr>
-
-<tr>
-<td> Pure Supplier
-<td> leaf node
-</tr>
-
-</table></center>
-<BR>
-<BR>
-
-<center><table cellpadding=1 border=1 cellspacing=4>
-<h4>EC Roles, Threading, and CORBA Roles</h4>
-
-<tr>
-<th> EC Roles
-<th> Activity
-<th> Thread Behavior
-<th> CORBA Roles
-</tr>
-
-<tr>
-<td> Pure Consumer
-<td> Passive
-<td> Threads optional, "internal", wait for an event to occur
-<td> Servant
-</tr>
-
-<tr>
-<td> Consumer/Supplier
-<td> Passive
-<td> Threads optional, "internal", wait for an event to occur
-<td> Client and/or Servant
-</tr>
-
-<tr>
-<td> Supplier/Consumer
-<td> Active
-<td> Threads required and visible to EC: consume events and actively produce other events
-<td> Client and/or Servant
-</tr>
-
-<tr>
-<td> Pure Supplier
-<td> Active
-<td> Threads required and visible to EC: actively produce events
-<td> Client
-</tr>
-</table></center>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<tr><td>
-<center><IMG SRC="http://www.cs.wustl.edu/~cdgill/ec_roles.GIF"></center>
-</table></center>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<tr><td>
-<center><IMG SRC="http://www.cs.wustl.edu/~cdgill/ec_roles2.GIF"></center>
-</table></center>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<tr><td>
-<center><IMG SRC="http://www.cs.wustl.edu/~cdgill/ec_backbone.GIF"></center>
-</table></center>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<tr><td>
-<center><IMG SRC="http://www.cs.wustl.edu/~cdgill/distributed_ec_roles.GIF"></center>
-</table></center>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<tr><td>
-<center><IMG SRC="http://www.cs.wustl.edu/~cdgill/ec_orb_view.GIF"></center>
-</table></center>
-
-<P><HR><P>
-<!-- ************************************************************ -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<tr><td>
-<center><h2><a name="Section4">Developing Consumers</a></h2></center>
-<br>
-<ul>
- <li> <a href="events_tutorial.html#Section4_1">Providing QoS Information</a>
- <li> <a href="events_tutorial.html#Section4_2">Connecting Consumers to the Event Channel</a>
- <li> <a href="events_tutorial.html#Section4_3">Receiving Events</a>
- <li> <a href="events_tutorial.html#Section4_4">Disconnecting Consumers from the Event Channel</a>
-</ul>
-</table></center>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-<center><table cellpadding=1 border=0 cellspacing=4>
-<center><h3><a name="Section4_1">Providing QoS Information</a><h3></center><p>
-
-<tr><td>
-The following steps are only necessary for applications that make use of the
-Event Service's hard real-time features. Applications that do not need these
-features and are configured with a null scheduler may skip the following
-operations on the scheduling server.
-
-<tr><td>
-For each operation, a Consumer should provide the worst case, expected, and
-cached execution time for that operation. It must also specify criticality and
-importance values for each operation. A real-time scheduler uses this information
-to order dispatches within a set of operations whose dependencies have been met.
-
-<tr><td>
-If it is a Consumer/Supplier (one which consumes an event and passively generates
-one or more events from the thread in which it was called, as illustrated in the
-tables above), it must provide dependencies on one or more other events to the
-scheduler.
-
-<tr><td>
-If it is a Supplier/Consumer (one which consumes an event and actively generates
-one or more events from its own thread, as illustrated in the tables above), it
-must also specify the rate at which it will generate the new events by passing a
-positive value in the period argument to the scheduler set method. It may also
-indicate a positive number of threads in which the dispatch will be made. If the
-number of threads given is zero, but a period is specified, the number of threads
-defaults to 1.
-
-</table>
-</center>
-
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-
-<tr><td>
-<pre>
-
- // Obtain a reference to the scheduler server.
- RtecScheduler::Scheduler_ptr server =
- ACE_Scheduler_Factory::server ();
-
- // Create new RT_Info descriptors for three events.
-
- RtecScheduler::handle_t handle1 =
- server->create ("event_1", // Name of entry point
- TAO_TRY_ENV // Environment
- );
-
- RtecScheduler::handle_t handle2 =
- server->create ("event_2", // Name of entry point
- TAO_TRY_ENV // Environment
- );
-
- RtecScheduler::handle_t handle3 =
- server->create ("event_3", // Name of entry point
- TAO_TRY_ENV // Environment
- );
-
-
- // Register as a consumer/supplier: act as a supplier of event_1 but with
- // a consumer dependency on event_3. Therefore, the actual period and
- // number of threads for event_1 depends on the characteristics of event_3.
- server->set (handle1, // RT_Info handle
- RtecScheduler::HIGH_CRITICALITY, // Criticality
- 500, // Worst case time (in 100 nanosecs)
- 500, // Typical time (in 100 nanosecs)
- 500, // Cached time (in 100 nanosecs)
- 0, // Period - will depend on event_3
- RtecScheduler::LOW_IMPORTANCE, // Importance
- 0, // Quantum (unused)
- 0, // Threads - will depend on event_3
- RtecScheduler::OPERATION, // Info type
- TAO_TRY_ENV);
-
- // Register as a producer of event_2.
- server->set (handle2, // RT_Info handle
- RtecScheduler::HIGH_CRITICALITY, // Criticality
- 500, // Worst case time (in 100 nanosecs)
- 500, // Typical time (in 100 nanosecs)
- 500, // Cached time (in 100 nanosecs)
- 50000 * 10, // Period in 100 nsec (= 20 Hz)
- RtecScheduler::LOW_IMPORTANCE, // Importance
- 0, // Quantum (unused)
- 1, // Threads
- RtecScheduler::OPERATION, // Info type
- TAO_TRY_ENV);
-
- // Register as a consumer of event_3.
- server->set (handle3, // RT_Info handle
- RtecScheduler::HIGH_CRITICALITY, // Criticality
- 500, // Worst case time (in 100 nanosecs)
- 500, // Typical time (in 100 nanosecs)
- 500, // Cached time (in 100 nanosecs)
- 0, // Period - will depend on supplier
- RtecScheduler::LOW_IMPORTANCE, // Importance
- 0, // Quantum (unused)
- 0, // Threads - will depend on supplier
- RtecScheduler::OPERATION, // Info type
- TAO_TRY_ENV);
-
-
- // Establish a dependency of event_1 on event_3.
- server->add_dependency (handle1, // handle that depends
- handle3, // handle that is depended on
- 1, // number of calls per event occurance
- TAO_TRY_ENV // environment
- );
-
-
-</pre>
-</table>
-</center>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<h3>
-<a name="Section4_2">Connecting Consumers to the Event Channel</a>
-</h3>
-
-<tr><td>
-The following code is derived from the EC_Throughput consumer code, which can be
-found in TAO in the file:
-<A HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/tests/EC_Throughput/ECT_Consumer.cpp">
-$TAO_ROOT/orbsvcs/tests/EC_Throughput/ECT_Consumer.cpp</a>
-
-<tr><td>
-<pre>
-
-void
-Test_Consumer::connect (const char* name,
- int event_a, int event_b,
- RtecEventChannelAdmin::EventChannel_ptr ec,
- CORBA::Environment& _env)
-{
-
- // Register operations with the scheduling service. The following steps are
- // only necessary for applications that make use of the Event Service's hard
- // real-time features. Applications that do not need these features and are
- // configured with a null scheduler may skip the following operations on the
- // scheduling server.
-
- // Obtain a reference to the scheduler from the ACE_Scheduler_Factory.
- RtecScheduler::Scheduler_ptr server =
- ACE_Scheduler_Factory::server ();
-
- // Create a new RT_Info entry for the function identifier
- // we were passed, and hang onto the handle to the RT_Info.
- RtecScheduler::handle_t rt_info =
- server->create (name, _env);
- TAO_CHECK_ENV_RETURN_VOID(_env);
-
- // Set the attributes for the RT_Info.
- ACE_Time_Value tv (0, 2000);
- TimeBase::TimeT time;
- ORBSVCS_Time::Time_Value_to_TimeT (time, tv);
- server->set (rt_info,
- RtecScheduler::VERY_HIGH_CRITICALITY,
- time, time, time,
- 0,
- RtecScheduler::VERY_LOW_IMPORTANCE,
- time,
- 0,
- RtecScheduler::OPERATION,
- _env);
- TAO_CHECK_ENV_RETURN_VOID(_env);
-
- // Specify a disjunctive dependency on the arrival of event_a, the arrival
- // of event b, OR the arrival of an event service shutdown event. Note that
- // the same RT_Info is used for each event. This can be used to simplify
- // code in applications using a null scheduler, or to consolidate events
- // with identical characteristics in hard real-time applications.
- ACE_ConsumerQOS_Factory qos;
- qos.start_disjunction_group ();
- qos.insert_type (ACE_ES_EVENT_SHUTDOWN, rt_info);
- qos.insert_type (event_a, rt_info);
- qos.insert_type (event_b, rt_info);
-
- // = Connect as a consumer.
-
- // Obtain a reference to the consumer administration object.
- RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =
- ec->for_consumers (_env);
- TAO_CHECK_ENV_RETURN_VOID(_env);
-
- // Obtain a reference to the push supplier proxy.
- this->supplier_proxy_ =
- consumer_admin->obtain_push_supplier (_env);
- TAO_CHECK_ENV_RETURN_VOID(_env);
-
- // Obtain a reference to this object.
- RtecEventComm::PushConsumer_var objref = this->_this (_env);
- TAO_CHECK_ENV_RETURN_VOID(_env);
-
- // Connect as a consumer.
- this->supplier_proxy_->connect_push_consumer (objref.in (),
- qos.get_ConsumerQOS (),
- _env);
- TAO_CHECK_ENV_RETURN_VOID(_env);
-}
-
-</pre>
-
-<tr><td>
-The following code is derived from the EC_Throughput consumer driver code, which
-can be found in TAO in the file:
-<A HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/tests/EC_Throughput/ECT_Consumer_Driver.cpp">
-$TAO_ROOT/orbsvcs/tests/EC_Throughput/ECT_Consumer_Driver.cpp</a>
-
-<tr><td>
-<pre>
-
-int
-ECT_Consumer_Driver::run (int argc, char* argv[])
-{
- // argc/argv are used to initialize the ORB and the options
- // for this particular test. Other applications may hard-code
- // the ORB options, obtain them from another source, etc.
-
- TAO_TRY
- {
- // The use of TAO_TRY macros isolate us from the differences
- // between platforms with and without native C++ exceptions.
- // This is work in progress and may change in the future!
-
- // Below is some boiler plate code to initialize the ORB and
- // the POA. Notice that applications that connect to the Event
- // Channel play the server role in some instances, because
- // they receive push() requests (as Consumers) or
- // disconnect_push_supplier() requests (as Suppliers).
-
- // Initialize the ORB reference.
- this->orb_ =
- CORBA::ORB_init (argc, argv, "", TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Initialize the root POA reference.
- CORBA::Object_var poa_object =
- this->orb_->resolve_initial_references("RootPOA");
- if (CORBA::is_nil (poa_object.in ()))
- ACE_ERROR_RETURN ((LM_ERROR,
- " (%P|%t) Unable to initialize the POA.\n"),
- 1);
-
- // Obtain the narrowed root POA reference.
- PortableServer::POA_var root_poa =
- PortableServer::POA::_narrow (poa_object.in (), TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Obtain a reference to the POA manager.
- PortableServer::POAManager_var poa_manager =
- root_poa->the_POAManager (TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Now some boiler plate code to obtain a reference to the
- // naming service.....
-
- // Resolve a reference to the naming service.
- CORBA::Object_var naming_obj =
- this->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);
-
- // Narrow the naming service reference.
- CosNaming::NamingContext_var naming_context =
- CosNaming::NamingContext::_narrow (naming_obj.in (), TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Use the Naming Service to locate the Scheduling Service and
- // use the Scheduler_Factory to keep a global pointer to the
- // latter.
-
- // Initialize the scheduler factory to operate in configuration mode.
- if (ACE_Scheduler_Factory::use_config (naming_context.in ()) == -1)
- return -1;
-
- // Use the Naming Service to locate the Event Service....
-
- // Set up the event service lookup name.
- CosNaming::Name name (1);
- name.length (1);
- name[0].id = CORBA::string_dup ("EventService");
-
- // Resolve a reference to the event service.
- CORBA::Object_var ec_obj =
- naming_context->resolve (name, TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Narrow the reference to the event service.
- RtecEventChannelAdmin::EventChannel_var channel;
- if (CORBA::is_nil (ec_obj.in ()))
- channel = RtecEventChannelAdmin::EventChannel::_nil ();
- else
- channel = RtecEventChannelAdmin::EventChannel::_narrow (ec_obj.in (),
- TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Activate the POA so we can start receiving requests...
-
- // Activate the POA manager.
- poa_manager->activate (TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Connect consumers to the event service.
- this->connect_consumers (channel.in (), TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- ACE_DEBUG ((LM_DEBUG, "connected consumer(s)\n"));
- ACE_DEBUG ((LM_DEBUG, "running the test\n"));
-
- // Run the event loop.
- if (this->orb_->run () == -1)
- ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "orb->run"), -1);
- ACE_DEBUG ((LM_DEBUG, "event loop finished\n"));
-
- this->dump_results ();
-
- // Disconnect consumers from the event service.
- this->disconnect_consumers (TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Destroy the event service.
- channel->destroy (TAO_TRY_ENV);
- TAO_CHECK_ENV;
- }
- TAO_CATCH (CORBA::SystemException, sys_ex)
- {
- TAO_TRY_ENV.print_exception ("SYS_EX");
- }
- TAO_CATCHANY
- {
- TAO_TRY_ENV.print_exception ("NON SYS EX");
- }
- TAO_ENDTRY;
- return 0;
-}
-
-</pre>
-</table>
-</center>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-
-<!-- Must be after suppliers connect. -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<h3><a name="Section4_3">Receiving Events</a></h3><p>
-
-<tr><td>
-The following code is derived from the EC_Throughput consumer code, which
-can be found in TAO in the file:
-<A HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/tests/EC_Throughput/ECT_Consumer.cpp">
-$TAO_ROOT/orbsvcs/tests/EC_Throughput/ECT_Consumer.cpp</a>
-
-<tr><td>
-<pre>
-
-void
-Test_Consumer::push (const RtecEventComm::EventSet& events,
- CORBA::Environment &_env)
-{
- // Make sure at least one event was pushed.
- if (events.length () == 0)
- {
- // ACE_DEBUG ((LM_DEBUG, "no events\n"));
- return;
- }
-
- // Make sure only one thread has access.
- ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->lock_);
-
- // We start the timer as soon as we receive the first event.
- if (this->recv_count_ == 0)
- this->timer_.start ();
-
- // Update the count of received events.
- this->recv_count_ += events.length ();
-
- if (TAO_debug_level > 0
- && this->recv_count_ % 1000 == 0)
- {
- ACE_DEBUG ((LM_DEBUG,
- "ECT_Consumer (%P|%t): %d events received\n",
- this->recv_count_));
- }
-
- // Loop through the events, looking for shutdown events.
- for (u_int i = 0; i < events.length (); ++i)
- {
- if (events[i].header.type == ACE_ES_EVENT_SHUTDOWN)
- {
- this->shutdown_count_++;
- if (this->shutdown_count_ >= this->n_suppliers_)
- {
- // We stop the timer as soon as we realize it is time to
- // do so.
- this->timer_.stop ();
- this->driver_->shutdown_consumer (this->cookie_, _env);
- }
- }
- }
-}
-
-</pre>
-</table>
-</center>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<h3>
-<a name="Section4_4">Disconnecting Consumers from the Event Channel</a>
-</h3>
-
-<tr><td>
-The following code is derived from the EC_Throughput consumer code, which can be
-found in TAO in the file:
-<A HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/tests/EC_Throughput/ECT_Consumer.cpp">
-$TAO_ROOT/orbsvcs/tests/EC_Throughput/ECT_Consumer.cpp</a>
-
-<tr><td>
-<pre>
-
-void
-Test_Consumer::disconnect (CORBA::Environment &_env)
-{
- // Make sure the supplier proxy reference is valid.
- if (CORBA::is_nil (this->supplier_proxy_.in ()))
- return;
-
- // Disconnect from further communication with the push
- // supplier(s). Each consumer is represented by a unique
- // ACE_ES_ConsumerModule instance. Which connection to
- // disconnect is determined by the instance for the consumer.
- this->supplier_proxy_->disconnect_push_supplier (_env);
- TAO_CHECK_ENV_RETURN_VOID(_env);
-
- // Mark the supplier proxy reference invalid.
- this->supplier_proxy_ =
- RtecEventChannelAdmin::ProxyPushSupplier::_nil ();
-
- // We want to stop processing events for this consumer. Above,
- // we disconnected the consumer from the Event Channel, so no
- // more events will be sent, but we could have some events in
- // transit.
-
- // Without a flushing protocol we need to deactivate the
- // servant to stop accepting push () requests for any
- // incoming events.
-
- // Deactivate the servant
- PortableServer::POA_var poa =
- this->_default_POA (_env);
- TAO_CHECK_ENV_RETURN_VOID (_env);
- PortableServer::ObjectId_var id =
- poa->servant_to_id (this, _env);
- TAO_CHECK_ENV_RETURN_VOID (_env);
- poa->deactivate_object (id.in (), _env);
- TAO_CHECK_ENV_RETURN_VOID (_env);
-}
-
-</pre>
-</table>
-</center>
-
-
-<P><HR><P>
-<!-- ************************************************************ -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<td>
-<h2><a name="Section5">Developing Suppliers</a></h2>
-
-<ul>
- <li> <a href="events_tutorial.html#Section5_1">Providing QoS Information</a>
- <li> <a href="events_tutorial.html#Section5_2">Connecting Suppliers to the Event Channel</a>
- <li> <a href="events_tutorial.html#Section5_3">Generating Events</a>
- <li> <a href="events_tutorial.html#Section5_4">Disconnecting Suppliers from the Event Channel</a>
-</ul>
-</table>
-</center>
-
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<h3><a name="Section5_1">Providing QoS Information</a></h3><p>
-<tr><td>
-In applications that use hard real-time scheduling, a Supplier should provide
-the worst case, expected, and cached execution time for each operation on the
-supplier side. Even if these values are small and highly deterministic, it is
-generally better to specify them in the supplier's RT_Info rather than folding
-them into the RT_Info of each consumer.
-
-<tr><td>
-Such a supplier must also specify criticality and importance values, a period,
-and the number of threads for each operation. A real-time scheduler propagates
-this information to consumer RT_Infos along the graph of dependencies. The
-scheduler then uses the propagated information to order dispatches within a
-set of operations whose dependencies have been met.
-
-<tr><td>
-The Event Service matches supplier publications with consumer subscriptions to
-provide efficient event filtering. Providing incorrect publications or
-subscriptions will result in missed events. The Event Service also uses the
-subscription information to create additional dependencies between registered
-RT_Infos. Thus, providing correct supplier publication and consumer
-subscription information is also critical for correct scheduling in hard
-real-time applications.
-
-
-<tr><td>
-As noted before in the discussion of consumers, the following steps are only
-necessary for applications that make use of the Event Service's hard real-time
-features. Applications that do not need these features and are configured
-with a null scheduler may skip the following operations on the scheduling
-server.
-
-</table>
-</center>
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-
-<tr><td>
-<pre>
-
- // Obtain a reference to the scheduler server.
- RtecScheduler::Scheduler_ptr server =
- ACE_Scheduler_Factory::server ();
-
- // Create new RT_Info descriptors for two events.
-
- RtecScheduler::handle_t handle0 =
- server->create ("event_0", // Name of entry point
- TAO_TRY_ENV // Environment
- );
-
- RtecScheduler::handle_t handle1 =
- server->create ("event_1", // Name of entry point
- TAO_TRY_ENV // Environment
- );
-
- // Register as a producer of event_0.
- server->set (handle0, // RT_Info handle
- RtecScheduler::HIGH_CRITICALITY, // Criticality
- 10, // Worst case time (in 100 nanosecs)
- 10, // Typical time (in 100 nanosecs)
- 10, // Cached time (in 100 nanosecs)
- 50000 * 10, // Period in 100 nanosecs (= 20 Hz)
- RtecScheduler::LOW_IMPORTANCE, // Importance
- 0, // Quantum (unused)
- 1, // Threads
- RtecScheduler::OPERATION, // Info type
- TAO_TRY_ENV);
-
- // Register as a producer of event_1.
- server->set (handle1, // RT_Info handle
- RtecScheduler::HIGH_CRITICALITY, // Criticality
- 10, // Worst case time (in 100 nanosecs)
- 10, // Typical time (in 100 nanosecs)
- 10, // Cached time (in 100 nanosecs)
- 50000 * 10, // Period in 100 nanosecs (= 20 Hz)
- RtecScheduler::LOW_IMPORTANCE, // Importance
- 0, // Quantum (unused)
- 1, // Threads
- RtecScheduler::OPERATION, // Info type
- TAO_TRY_ENV);
-
-</pre>
-</table>
-</center>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<td>
-<h3><a name="Section5_2">Connecting Suppliers to Event Channel</a></h3><P>
-<p>
-
-<tr><td>
-The following code is derived from the EC_Throughput supplier code, which
-can be found in TAO in the file:
-<A HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/tests/EC_Throughput/ECT_Supplier.cpp">
-$TAO_ROOT/orbsvcs/tests/EC_Throughput/ECT_Supplier.cpp</a>
-
-
-<tr><td>
-<pre>
-
-void
-Test_Supplier::connect (const char* name,
- int burst_count,
- int burst_size,
- int event_size,
- int burst_pause,
- int event_a,
- int event_b,
- RtecEventChannelAdmin::EventChannel_ptr ec,
- CORBA::Environment &_env)
-{
- // Some application-specific setup code.
-
- // Store the passed parameters in the object.
- this->burst_count_ = burst_count;
- this->burst_size_ = burst_size;
- this->event_size_ = event_size;
- this->burst_pause_ = burst_pause;
- this->event_a_ = event_a;
- this->event_b_ = event_b;
-
- // Register operations with the scheduling service. The following steps are
- // only necessary for applications that make use of the Event Service's hard
- // real-time features. Applications that do not need these features and are
- // configured with a null scheduler may skip the following operations on the
- // scheduling server.
-
- // Obtain a reference to the scheduling service.
- RtecScheduler::Scheduler_ptr server =
- ACE_Scheduler_Factory::server ();
-
- // Create an RT_Info descriptor for the passed operation name.
- RtecScheduler::handle_t rt_info =
- server->create (name, _env);
- TAO_CHECK_ENV_RETURN_VOID (_env);
-
- // Calculate the period at which to supply events.
- ACE_Time_Value tv (0, burst_pause);
- RtecScheduler::Period_t rate = tv.usec () * 10;
-
- // Set the information in the RT_Info descriptor.
- tv.set (0, 2000);
- TimeBase::TimeT time;
- ORBSVCS_Time::Time_Value_to_TimeT (time, tv);
- server->set (rt_info,
- RtecScheduler::VERY_HIGH_CRITICALITY,
- time, time, time,
- rate,
- RtecScheduler::VERY_LOW_IMPORTANCE,
- time,
- 1,
- RtecScheduler::OPERATION,
- _env);
- TAO_CHECK_ENV_RETURN_VOID (_env);
-
- // Now, create a supplier id, and publish the events
- // that will be supplied under this id.
-
- // Create a supplier id from the passed name
- this->supplier_id_ = ACE::crc32 (name);
- ACE_DEBUG ((LM_DEBUG, "ID for <%s> is %04.4x\n", name,
- this->supplier_id_));
-
- // Publish the events the supplier provides.
- ACE_SupplierQOS_Factory qos;
- qos.insert (this->supplier_id_,
- event_a,
- rt_info, 1);
- qos.insert (this->supplier_id_,
- event_b,
- rt_info, 1);
- qos.insert (this->supplier_id_,
- ACE_ES_EVENT_SHUTDOWN,
- rt_info, 1);
-
- // And finally, some boiler plate code to connect a supplier
- // to the Event Service. This is where the connection is
- // actually made.
-
- // Obtain a reference to the supplier administration object.
- RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =
- ec->for_suppliers (_env);
- TAO_CHECK_ENV_RETURN_VOID (_env);
-
- // Obtain a reference to the consumer proxy object.
- this->consumer_proxy_ =
- supplier_admin->obtain_push_consumer (_env);
- TAO_CHECK_ENV_RETURN_VOID (_env);
-
- // Obtain a reference to this supplier object.
- RtecEventComm::PushSupplier_var objref =
- this->supplier_._this (_env);
- TAO_CHECK_ENV_RETURN_VOID (_env);
-
- // Connect as a supplier of the published events.
- this->consumer_proxy_->connect_push_supplier (objref.in (),
- qos.get_SupplierQOS (),
- _env);
- TAO_CHECK_ENV_RETURN_VOID (_env);
-}
-
-</pre>
-
-
-<tr><td>
-The following code is derived from the EC_Throughput supplier driver code, which
-can be found in TAO in the file:
-<A HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/tests/EC_Throughput/ECT_Supplier_Driver.cpp">
-$TAO_ROOT/orbsvcs/tests/EC_Throughput/ECT_Supplier_Driver.cpp</a>
-
-<tr><td>
-<pre>
-
-int
-ECT_Supplier_Driver::run (int argc, char* argv[])
-{
- // argc/argv are used to initialize the ORB and the options
- // for this particular test. Other applications may hard-code
- // the ORB options, obtain them from another source, etc.
-
- TAO_TRY
- {
- // The use of TAO_TRY macros isolate us from the differences
- // between platforms with and without native C++ exceptions.
- // This is work in progress and may change in the future!
-
- // Below is some boiler plate code to initialize the ORB and
- // the POA. Notice that applications that connect to the Event
- // Channel play the server role in some instances, because
- // they receive push() requests (as Consumers) or
- // disconnect_push_supplier() requests (as Suppliers).
-
- // Initialize the ORB reference.
- CORBA::ORB_var orb =
- CORBA::ORB_init (argc, argv, "", TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Initialize the root POA reference.
- CORBA::Object_var poa_object =
- orb->resolve_initial_references("RootPOA");
- if (CORBA::is_nil (poa_object.in ()))
- ACE_ERROR_RETURN ((LM_ERROR,
- " (%P|%t) Unable to initialize the POA.\n"),
- 1);
-
- // Obtain the narrowed root POA reference.
- PortableServer::POA_var root_poa =
- PortableServer::POA::_narrow (poa_object.in (), TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Obtain a reference to the POA manager.
- PortableServer::POAManager_var poa_manager =
- root_poa->the_POAManager (TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
-
- // Now some boiler plate code to obtain a reference to the
- // naming service.....
-
- // Resolve a reference to 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);
-
- // Narrow the naming service reference.
- CosNaming::NamingContext_var naming_context =
- CosNaming::NamingContext::_narrow (naming_obj.in (), TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Use the Naming Service to locate the Scheduling Service and
- // use the Scheduler_Factory to keep a global pointer to the
- // latter.
-
- // Initialize the scheduler factory to operate in configuration mode.
- if (ACE_Scheduler_Factory::use_config (naming_context.in ()) == -1)
- return -1;
-
- // Use the Naming Service to locate the Event Service....
-
- // Set up the event service lookup name.
- CosNaming::Name name (1);
- name.length (1);
- name[0].id = CORBA::string_dup ("EventService");
-
- // Resolve a reference to the event service.
- CORBA::Object_var ec_obj =
- naming_context->resolve (name, TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Narrow the reference to the event service.
- RtecEventChannelAdmin::EventChannel_var channel;
- if (CORBA::is_nil (ec_obj.in ()))
- channel = RtecEventChannelAdmin::EventChannel::_nil ();
- else
- channel = RtecEventChannelAdmin::EventChannel::_narrow (ec_obj.in (),
- TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Activate the POA so we can start receiving requests...
-
- // Activate the POA manager.
- poa_manager->activate (TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Connect suppliers to the event service.
- this->connect_suppliers (channel.in (), TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- ACE_DEBUG ((LM_DEBUG, "connected supplier(s)\n"));
-
- // Activate the supplier objects
- this->activate_suppliers (TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- ACE_DEBUG ((LM_DEBUG, "suppliers are active\n"));
-
- // Wait for the supplier threads.
- if (ACE_Thread_Manager::instance ()->wait () == -1)
- {
- ACE_ERROR ((LM_ERROR, "Thread_Manager wait failed\n"));
- return 1;
- }
-
- ACE_DEBUG ((LM_DEBUG, "suppliers finished\n"));
-
- this->dump_results ();
-
- // Disconnect suppliers from the event service.
- this->disconnect_suppliers (TAO_TRY_ENV);
- TAO_CHECK_ENV;
- }
- TAO_CATCH (CORBA::SystemException, sys_ex)
- {
- TAO_TRY_ENV.print_exception ("SYS_EX");
- }
- TAO_CATCHANY
- {
- TAO_TRY_ENV.print_exception ("NON SYS EX");
- }
- TAO_ENDTRY;
- return 0;
-}
-
-</pre>
-</table>
-</center>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<h3><a name="Section5_3">Generating Events</a></h3><P><p>
-
-<tr><td>
-The following code is derived from the EC_Throughput supplier code, which
-can be found in TAO in the file:
-<A HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/tests/EC_Throughput/ECT_Supplier.cpp">
-$TAO_ROOT/orbsvcs/tests/EC_Throughput/ECT_Supplier.cpp</a>
-
-<tr><td>
-<pre>
-
-int
-Test_Supplier::svc ()
-{
- TAO_TRY
- {
- // First, a bunch of code that is specific to this test.
-
- // Set pause (sleep) value between message bursts.
- ACE_Time_Value tv (0, this->burst_pause_);
-
- // Set up message block for event data.
- ACE_Message_Block mb (this->event_size_);
- mb.wr_ptr (this->event_size_);
-
- // Create an event set for one event, initialize event header.
- RtecEventComm::EventSet event (1);
- event.length (1);
- event[0].header.source = this->supplier_id ();
- event[0].header.ttl = 1;
-
- // Set up time stamps in event header. This is for performance
- // measurements, so this step can be omitted at will.
- ACE_hrtime_t t = ACE_OS::gethrtime ();
- ORBSVCS_Time::hrtime_to_TimeT (event[0].header.creation_time, t);
- event[0].header.ec_recv_time = ORBSVCS_Time::zero;
- event[0].header.ec_send_time = ORBSVCS_Time::zero;
-
- // Initialize data fields in event.
- event[0].data.x = 0;
- event[0].data.y = 0;
-
- // We use replace to minimize the copies. This should result
- // in just one memory allocation;
- event[0].data.payload.replace (this->event_size_,
- &mb);
-
- // This is where the events are actually pushed into
- // the event channel. The test pushes bursts of events,
- // pausing a specified interval between bursts.
-
- // Start the timer, and begin pushing events.
- this->timer_.start ();
- for (int i = 0; i < this->burst_count_; ++i)
- {
- // Send a burst of events.
- for (int j = 0; j < this->burst_size_; ++j)
- {
- if (j % 2 == 0)
- event[0].header.type = this->event_a_;
- else
- event[0].header.type = this->event_b_;
-
- // ACE_DEBUG ((LM_DEBUG, "(%t) supplier push event\n"));
- this->consumer_proxy ()->push (event, TAO_TRY_ENV);
-
- TAO_CHECK_ENV;
- }
-
- // Sleep until it's time to send the next burst.
- ACE_OS::sleep (tv);
- }
-
- // Send a "magic" type of event to inform the consumer that we are
- // not sending anything else...
-
- // Send one event shutdown from each supplier
- event[0].header.type = ACE_ES_EVENT_SHUTDOWN;
- this->consumer_proxy ()->push(event, TAO_TRY_ENV);
- TAO_CHECK_ENV;
- this->timer_.stop ();
-
- }
- TAO_CATCH (CORBA::SystemException, sys_ex)
- {
- TAO_TRY_ENV.print_exception ("SYS_EX");
- }
- TAO_CATCHANY
- {
- TAO_TRY_ENV.print_exception ("NON SYS EX");
- }
- TAO_ENDTRY;
- return 0;
-}
-
-</pre>
-</table>
-</center>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<td>
-<h3><a name="Section5_4">Disconnecting Suppliers from the Event Channel</a></h3><P>
-<p>
-
-<tr><td>
-The following code is derived from the EC_Throughput supplier code, which
-can be found in TAO in the file:
-<A HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/tests/EC_Throughput/ECT_Supplier.cpp">
-$TAO_ROOT/orbsvcs/tests/EC_Throughput/ECT_Supplier.cpp</a>
-
-
-<tr><td>
-<pre>
-
-void
-Test_Supplier::disconnect (CORBA::Environment &_env)
-{
- // Make sure the consumer proxy reference is valid.
- if (CORBA::is_nil (this->consumer_proxy_.in ()))
- return;
-
- // Disconnect communication with the push consumer(s).
- this->consumer_proxy_->disconnect_push_consumer (_env);
- TAO_CHECK_ENV_RETURN_VOID (_env);
-
- // Mark the consumer proxy reference invalid.
- this->consumer_proxy_ =
- RtecEventChannelAdmin::ProxyPushConsumer::_nil ();
-
- // We need to stop accepting disconnect_push_supplier () requests
- // for this supplier, before it is safe to destroy the supplier.
- // As required by the CORBA spec, you must explicitly deactivate
- // a servant before destroying it.
-
- // Deactivate the servant
- PortableServer::POA_var poa =
- this->supplier_._default_POA (_env);
- TAO_CHECK_ENV_RETURN_VOID (_env);
- PortableServer::ObjectId_var id =
- poa->servant_to_id (&this->supplier_, _env);
- TAO_CHECK_ENV_RETURN_VOID (_env);
- poa->deactivate_object (id.in (), _env);
- TAO_CHECK_ENV_RETURN_VOID (_env);
- RtecEventChannelAdmin::ProxyPushConsumer::_nil ();
-}
-
-</pre>
-
-</table>
-</center>
-
-<P><HR><P>
-<!-- ************************************************************ -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<td>
-<h2><a name="Section6">Caring for your Event Channel</a></h2>
-
-
-<BR>
-
-<ul>
- <li> <a href="events_tutorial.html#Section6_1">Creation and Name Service Registration</a>
- <li> <a href="events_tutorial.html#Section6_2">Register Suppliers Before Consumers</a>
-</ul>
-</table>
-</center>
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<h3><a name="Section6_1">Creation and Name Service Registration</a><h3><p>
-
-<tr><td>
-The following code is derived from the Event_Service executable, which can be
-found in TAO in the file:
-<A HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/Event_Service/Event_Service.cpp">
-$TAO_ROOT/orbsvcs/Event_Service/Event_Service.cpp</a>
-
-<tr><td>
-<pre>
-
-int main (int argc, char *argv[])
-{
- TAO_TRY
- {
- // argc/argv are used to initialize the ORB and the options
- // for the Event Service executable. Other applications may
- // hard code the ORB options, obtain them from another source, etc.
-
- // Again the boiler plate code for ORB and POA initialization.
-
- // Initialize ORB.
- CORBA::ORB_var orb =
- CORBA::ORB_init (argc, argv, "internet", TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- if (parse_args (argc, argv) == -1)
- return 1;
-
- CORBA::Object_var poa_object =
- orb->resolve_initial_references("RootPOA");
- if (CORBA::is_nil (poa_object.in ()))
- ACE_ERROR_RETURN ((LM_ERROR,
- " (%P|%t) Unable to initialize the POA.\n"),
- 1);
-
- PortableServer::POA_var root_poa =
- PortableServer::POA::_narrow (poa_object.in (), TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- PortableServer::POAManager_var poa_manager =
- root_poa->the_POAManager (TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- 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 initialize the Naming Service.\n"),
- 1);
-
- CosNaming::NamingContext_var naming_context =
- CosNaming::NamingContext::_narrow (naming_obj.in (), TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Notice the use of auto_ptr<> to automagically manage the
- // destruction of the servant. When the auto_ptr goes out
- // of scope, its destructor is called, which in turn destroys
- // the servant.
-
- auto_ptr<POA_RtecScheduler::Scheduler> scheduler_impl;
- RtecScheduler::Scheduler_var scheduler;
-
-
- // Create a new servant to implement the Scheduling Service,
- // register it with the Naming Service, and use the
- // Scheduler_Factory to keep a global pointer to the new
- // Scheduling Service.
-
- // This is the name we (potentially) use to register the Scheduling
- // Service in the Naming Service.
- CosNaming::Name schedule_name (1);
- schedule_name.length (1);
- schedule_name[0].id = CORBA::string_dup ("ScheduleService");
-
- if (global_scheduler == 0)
- {
- scheduler_impl =
- auto_ptr<POA_RtecScheduler::Scheduler>(new ACE_Config_Scheduler);
- if (scheduler_impl.get () == 0)
- return 1;
- scheduler = scheduler_impl->_this (TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- CORBA::String_var str =
- orb->object_to_string (scheduler.in (), TAO_TRY_ENV);
- TAO_CHECK_ENV;
- ACE_DEBUG ((LM_DEBUG, "The (local) scheduler IOR is <%s>\n",
- str.in ()));
-
- // Register the servant with the Naming Context....
- naming_context->bind (schedule_name, scheduler.in (), TAO_TRY_ENV);
- TAO_CHECK_ENV;
- }
-
- ACE_Scheduler_Factory::use_config (naming_context.in ());
-
- // The Event Service can be configured to support priority based
- // dispatching (the "default_Module_Factory") or best effort (the
- // "Reactive_Module_Factory"). We pick the right module factory
- // according to the command line options processed above.
-
- TAO_Default_Module_Factory default_module_factory;
- TAO_Reactive_Module_Factory reactive_module_factory;
-
- TAO_Module_Factory* module_factory = &default_module_factory;
- if (reactive)
- module_factory = &reactive_module_factory;
-
- // Now, create a new event channel servant to implement the
- // Event Service, and register it with Naming Service.
-
- // Construct the event channel using the given module factory.
- ACE_EventChannel ec_impl (1,
- ACE_DEFAULT_EVENT_CHANNEL_TYPE,
- module_factory);
-
- // Obtain an object reference to the new channel.
- RtecEventChannelAdmin::EventChannel_var ec =
- ec_impl._this (TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Convert the EC object reference to a string.
- CORBA::String_var str =
- orb->object_to_string (ec.in (), TAO_TRY_ENV);
-
- // Output the EC object reference string (debug only).
- ACE_DEBUG ((LM_DEBUG,
- "The EC IOR is <%s>\n", str.in ()));
-
- // Register the EC with the Naming Service.
- CosNaming::Name channel_name (1);
- channel_name.length (1);
- channel_name[0].id = CORBA::string_dup (service_name);
- naming_context->bind (channel_name, ec.in (), TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Activate the POA so we can start receiving requests...
-
- // Activate the POA manager.
- poa_manager->activate (TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- // Run the ORB event loop
- ACE_DEBUG ((LM_DEBUG, "%s; running event service\n", __FILE__));
- if (orb->run () == -1)
- ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "run"), 1);
-
- // Now the Event Service is finished. We could deactivate the
- // EC and SS here, but we don't need to, as the server is
- // going down anyway.
-
-
- // Remove the event service and the scheduling service from
- // the Naming Service.
-
- naming_context->unbind (channel_name, TAO_TRY_ENV);
- TAO_CHECK_ENV;
-
- if (global_scheduler == 0)
- {
- naming_context->unbind (schedule_name, TAO_TRY_ENV);
- TAO_CHECK_ENV;
- }
-
- }
- TAO_CATCHANY
- {
- TAO_TRY_ENV.print_exception ("EC");
- }
- TAO_ENDTRY;
-
-
- return 0;
-}
-
-</pre>
-</table>
-</center>
-
-<P><hr width="75%"><P> <!-- intra-section separator -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<h3><a name="Section6_2">Register Suppliers before Consumers</a></h3><p>
-<BR>
-<BR>
-<tr><td>
-<center>
-<IMG SRC="http://www.cs.wustl.edu/~schmidt/gifs/ec_registration.gif">
-</center>
-</table></center>
-
-<P><HR><P>
-<!-- ************************************************************ -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<tr><td>
-<h2><a name="Section7">Sample Applications</a></h2>
-
-<tr><td>
-A number of sample applications are available in the directories under
-<a href="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/tests/">
-TAO's ORB Services tests</a>.
-
-<tr><td>
-In particular, much of the code shown in this tutorial was drawn from the
-<a href="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/tests/EC_Throughput/">
-EC_Throughput</a> test. This test exercises the Event Service and measures its
-throughput capabilities.
-
-<tr><td>
-A similar test,
-<a href="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/tests/Event_Latency/">
-Event_Latency</a>, measures the latency of events through the Event Service.
-
-<tr><td>
-The
-<a href="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/tests/EC_Basic/">
-EC_Basic</a> test demonstrates the basic use the Event Service.
-
-<tr><td>
-The
-<a href="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/tests/EC_Multiple/">
-EC_Multiple</a> test shows a number of ways to connect multiple Event Channels.
-
-
-<tr><td>
-For the IDL source for the various interfaces, please see
-<a href="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/orbsvcs/RtecScheduler.idl">RtecScheduler.idl</a>,
-<a href="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/orbsvcs/CosEventChannelAdmin.idl">CosEventChannelAdmin.idl</a>,
-<a href="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/orbsvcs/CosEventComm.idl">CosEventComm.idl</a>
-and
-<a href="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/orbsvcs/orbsvcs/CosNaming.idl">CosNaming.idl</a>.
-
-
-</table>
-</center>
-
-<P><HR><P>
-<!-- ************************************************************ -->
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<tr><td>
-<h2><a name="Section8">Reference Materials</a></h2>
-
-<tr><td>
-The following materials were used in developing this tutorial: please refer to them for further information.
-
-<tr><td>
-<br>
-<tr><td>
-<h3>Books</h3>
-
-<tr><td>
-Mowbray, T. and Zahavi, R. The Essential CORBA, Systems Integration Using Distributed Objects. Wiley, 1995.
-ISBN 0-471-10611-9
-
-<tr><td>
-<br>
-
-<tr><td>
-Baker, S. CORBA Distributed Objects Using Orbix. Addison-Wesley, 1997. ISBN 0-201-92475-7
-
-<tr><td>
-<br>
-<tr><td>
-<h3>Papers</h3>
-
-<tr><td>
-<ul>
-
-<li><a href="http://www.cs.wustl.edu/~schmidt/Arch.ps.gz">
-Architectural Considerations for Deterministic Real-Time ORB
-Endsystems and Applications</a>
-
-<li><a href="http://www.cs.wustl.edu/~schmidt/JSAC-98.ps.gz"> The
-Design and Performance of a Real-Time CORBA Object Event Service</a>
-
-<li><a href="http://www.cs.wustl.edu/~schmidt/RT-ORB.ps.gz"> The
-Design of the TAO Real-Time Object Request Broker</a>
-
-</ul>
-
-
-<tr><td>
-
-</table>
-</center>
-
-<P><HR><P>
-<!-- ************************************************************ -->
-
-
-<center><table cellpadding=1 border=0 cellspacing=4>
-<tr><td>
-Last modified 10:50:30 CST 22 December 1998 by Chris Gill
-</table></center>
-
-</body></html>
-