RTI Connext Java API Version 7.3.0
|
<<interface>> Abstract base class for all Listener interfaces. More...
<<interface>> Abstract base class for all Listener interfaces.
All the supported kinds of concrete com.rti.dds.infrastructure.Listener interfaces (one per concrete com.rti.dds.infrastructure.Entity type) derive from this root and add methods whose prototype depends on the concrete Listener.
Listeners provide a way for RTI Connext to asynchronously alert the application when there are relevant status changes.
Almost every application will have to implement listener interfaces.
Each dedicated listener presents a list of operations that correspond to the relevant communication status changes to which an application may respond.
The same com.rti.dds.infrastructure.Listener instance may be shared among multiple entities if you so desire. Consequently, the provided parameter contains a reference to the concerned com.rti.dds.infrastructure.Entity.
The general mapping between the plain communication statuses (see Status Kinds) and the listeners' operations is as follows:
on_<communication_status>
(), which takes a parameter of type <communication_status>
as listed in Status Kinds. on_<communication_status>
is available on the relevant com.rti.dds.infrastructure.Entity as well as those that embed it, as expressed in the following figure: listener processing. The most specific relevant enabled listener is called."
This behavior allows the application to set a default behavior (e.g., in the listener associated with the com.rti.dds.domain.DomainParticipant) and to set dedicated behaviors only where needed.
The two statuses related to data arrival are treated slightly differently. Since they constitute the core purpose of the Data Distribution Service, there is no need to provide a default mechanism (as is done for the plain communication statuses above).
The rule is as follows. Each time the read communication status changes:
The rationale is that either the application is interested in relations among data arrivals and it must use the first option (and then get the corresponding com.rti.dds.subscription.DataReader objects by calling com.rti.dds.subscription.Subscriber.get_datareaders on the related com.rti.dds.subscription.Subscriber and then get the data by calling com.rti.ndds.example.FooDataReader.read or com.rti.ndds.example.FooDataReader.take on the returned com.rti.dds.subscription.DataReader objects), or it wants to treat each com.rti.dds.subscription.DataReader independently and it may choose the second option (and then get the data by calling com.rti.ndds.example.FooDataReader.read or com.rti.ndds.example.FooDataReader.take on the related com.rti.dds.subscription.DataReader).
Note that if com.rti.dds.subscription.SubscriberListener.on_data_on_readers is called, RTI Connext will not try to call com.rti.dds.subscription.DataReaderListener.on_data_available. However, an application can force a call to the com.rti.dds.subscription.DataReader objects that have data by calling com.rti.dds.subscription.Subscriber.notify_datareaders.
See Restricted Operations in Listener Callbacks, in the Core Libraries User's Manual.
Note that all the issues described below are avoided by using com.rti.dds.infrastructure.WaitSet.
Avoid blocking or performing a lot of processing in Listener callbacks
Listeners are invoked by internal threads that perform critical functions within the middleware and need to run in a timely manner. By default, Connext DDS creates a few threads to use to receive data and only a single thread to handle periodic events.
Because of this, user applications installing Listeners should never block in a Listener callback. There are several negative consequences of blocking in a listener callback:
If the application needs to make a blocking call when data is available, or when another event occurs, the application should use com.rti.dds.infrastructure.WaitSet.
Avoid taking application mutexes/semaphores in Listener callbacks
Taking application mutexes/sempahores within a Listener callback may lead to unexpected deadlock scenarios.
When a Listener callback is invoked the EA (Exclusive Area) of the Entity 'E' to which the callback applies is taken by the middleware.
If the application takes an application mutex 'M' within a critical section in which the application makes DDS calls affecting 'E', this may lead to following deadlock:
The middleware thread is within the entity EA trying to acquire the mutex 'M'. At the same time, the application thread has acquired 'M' and is blocked trying to acquire the entity EA.
Do not write data with a DataWriter within the on_data_available callback
Avoid writing data with a DataWriter within the com.rti.dds.subscription.DataReaderListener::on_data_available() callback. If the write operation blocks because e.g. the send window is full, this will lead to a deadlock.
Do not call wait_for_acknowledgements within the on_data_available callback
Do not call the com.rti.dds.publication.DataWriter.wait_for_acknowledgments within the com.rti.dds.subscription.DataReaderListener::on_data_available() callback. This will lead to deadlock.