ACE_Stream is handy when you have several ACE_Task objects that you would like to link together.
An intermediate class you we will deal with is the ACE_Module.
The basic plan is to wrap your Task into a Module, push the Module onto the Stream. Do this for each Task, and then inject Message_Blocks into the Stream.
Each Task then processes the Message_Block, and forwards it on to the next Task in the Stream.
If you are not already familiar with Message_Blocks and Message_Queues, I highly suggest that you check out Tutorials 10-13.
Streams can be used for both downstream and upstream movement of messages. Used this way mirrors closely the way System V STREAMS work. But you don't have to use them bidirectionally. In this tutorial, we only use one direction of the Stream. Down.
This tutorial is contributed by Bob McWhirter (firstname.lastname@example.org)
The task implementation makes use of flags to decide on whether to close the main task or the service thread. The svc () method follows the golden rule of copying message blocks before putting them on the queue until it comes across a hang-up message. It then puts the message back on the queue for its peers to obtain it and exits.
Any message put onto the Tail module is an error. So a customised derivative of the Task class is created, which collects all the garbage messages put onto the Tail. This End_Task is put into the Stream at the start itself such that no modules whould ever follow it!
Then the other modules are pushed from the Tail-end into the Stream. This is because we are interested in writing and not reading. (Picture this to be a FIFO (queue) with head and tail nodes such that the nodes are removed from the front and put into the queue from the back)
Each module then opens up the task which spawns threads and begins to shove messgaes down the stream. Once we have got all the messages into the stream, our job is completed and we shut down the Stream.
A simple way to wade down the stream...;)