Threading
For events being delivered from the correlator to a chain towards the transport, the correlator will only ever call sendBatchTowardsTransport from a single thread at a time. Most codecs will call the next component in the chain in the thread that invoked them, but are not required to. A codec can queue events and drain the queue from a separate thread if desired.
Transports and codecs should only make a single call at a time to the hostSide plug-in (and thus only one thread at a time passes events towards the host) as the next plug-in may not be thread-safe. Similarly, codecs should only make one call at a time to the transportSide plug-in, though one codec may have threads invoking both hostSide and transportSide concurrently. Plug-ins should not assume that they are called on the same thread each time (in particular, the correlator will use different threads for sending batches of events), but they can assume that no more than one thread at a time sends events to the transport.
Transports and codecs will typically be processing events towards the transport and towards the host in different threads concurrently. The start, hostReady and shutdown methods will be called from different threads to any other operation and while other calls are in progress.
When a chain is disconnected or when the correlator is shut down, the shutdown method on the plug-in is called. This should ensure the following:
Any threads calling into the plug-in which are blocked in the plug-in (particularly for transports) should unblock and return.
Any threads that the plug-in has started have been stopped and joined.
The plug-in should ensure any in-progress calls out to other plug-ins have completed.
The plug-in must ensure no more calls are made out of a plug-in to send messages to other plug-ins.
This is particularly important for C++ plug-ins. Methods calling out after returning from shutdown, or in progress at the point the shutdown method completes, could cause a crash. In practice, a plug-in that starts a thread to read from a socket or other connection and send messages towards the host should close the socket and join the thread (waiting for it to terminate) to meet these requirements.
For C++ plug-ins, we recommend use of the standard libraries such as
std::thread and
std::mutex for managing threads and locking in plug-ins. If not available, we provide some simple macros in the
sag_connectivity_threading.h header file. See the
API Reference for C++ (Doxygen) for using it.