STREAMS Programming Guide

Exit Print View

Updated: July 2014
 
 

Message Processing Procedures

Typically, put procedures are required in pushable modules, but service procedures are optional. If the put routine queues messages, a corresponding service routine must be present to handle the queued messages. If the put routine does not queue messages, the service routine is not required.

Figure 7–10 shows typical processing flow for a put procedure which works as follows:

  • A message is received by the put procedure associated with the queue, where some processing can be performed on the message.

  • The put procedure determines if the message can be sent to the next module by the use of canput(9F) or canputnext(9F).

  • If the next module is flow controlled, the put procedure queues the message using putq(9F).

  • putq(9F) places the message in the queue based on its priority.

  • Then, putq(9F) makes the queue ready for execution by the STREAMS scheduler, following all other queues currently scheduled.

  • If the next module is not flow controlled, the put procedure does any processing needed on the message and sends it to the next module using putnext(9F). Note that if the module does not have a service procedure it cannot queue the message, and must process and send the message to the next module.

Figure 7–11 shows typical processing flow for a service procedure that works as follows:

  • When the system goes from kernel mode to user mode, the STREAMS scheduler calls the service procedure.

  • The service procedure gets the first message (q_first) from the message queue using the getq(9F) utility.

  • The put procedure determines if the message can be sent to the next module using canput(9F) or canputnext(9F).

  • If the next module is flow controlled, the put procedure requeues the message with putbq(9F), and then returns.

  • If the next module is not flow controlled, the service procedure processes the message and passes it to the put procedure of the next queue with putnext(9F).

  • The service procedure gets the next message and processes it. This processing continues until the queue is empty or flow control blocks further processing. The service procedure returns to the caller.


Caution

Caution  - A service or put procedure must never block since it has no user context. It must always return to its caller.


If no processing is required in the put procedure, the procedure does not have to be explicitly declared. Rather, putq(9F) can be placed in the qinit(9S) structure declaration for the appropriate queue side to queue the message for the service procedure. For example:

static struct qinit winit = { putq, modwsrv, ...... };

More typically, put procedures process high-priority messages to avoid queueing them.

Device drivers associated with hardware are examples of STREAMS devices that might not have a put procedure. Since there are no queues below the hardware level, another module does not call the module's put procedure. Data comes into the stream from an interrupt routine, and is either processed or queued for the service procedure.

A STREAMS filter is an example of a module without a service procedure—messages passed to it are either passed or filtered. Flow control is described in Flow Control in Service Procedures.

The key attribute of a service procedure in the STREAMS architecture is delayed processing. When a service procedure is used in a module, the module developer is implying that there are other, more time-sensitive activities to be performed elsewhere in this stream, in other streams, or in the system in general.


Note -  The presence of a service procedure is mandatory if the flow control mechanism is to be utilised by the queue. If you do not implement flow control, queues can overflow and hang the system.