A STREAMS module does processing operations on messages passing from a Stream head to a driver or from a driver to a Stream-head. For example, a TCP module might add header information to the front of data passing downstream through it. Not every Stream requires a module. There can be zero or more modules in a Stream.
Modules are stacked (pushed) onto and unstacked (popped) from a Stream. Each module must provide open(), close(), and put() entries and provides a service() entry if the module supports flow control.
Like the Stream-head, each module contains a pair of queue structures, although a module only queues data if it is implementing flow control. Figure 1-4 shows the queue structures Au/Ad associated with Module A ("u" for upstream" "d" for downstream) and Bu/Bd associated with Module B.
The two queues operate completely independently. Messages and data can be shared between upstream and downstream queues only if the module functions are specifically programed to share data.
Within a module, one queue can refer to the messages and data of the opposing queue. A queue can directly refer to the queue of the successor module (adjacent in the direction of message flow). For example, in Figure 1-4, Au-the upstream queue from Module A, can reference Bu-the upstream queue from Module B. Similarly Queue Bd can reference Queue Ad.
Both queues in a module contain messages, processing procedures, and private data:
Blocks of data that pass through, and can be operated on by a module.
Individual put and service routines on the read and write queues process messages. The put procedure passes messages from one queue to the next in a stream and is required for each queue. It can do additional message processing. The service procedure is optional and does deferred processing of messages. These procedures can send messages either upstream or downstream. Both procedures can also modify the private data in their module.
Data private to the module (for example, state information and translation tables).
Entry points must be provided. The open routine is invoked when the module is pushed onto the Stream or the Stream is reopened. The close is invoked when the module is popped or the Stream is closed.
A module is initialized by either an I_PUSH ioctl(2), or pushed automatically during an open if a Stream has been configured by the autopush(1M) mechanism, or if that Stream is reopened
A module is disengaged by close or the I_POP ioctl(2)