STREAMS-UX Programmer's Guide (February 2007)
Modules and Drivers
Design Guidelines
Chapter 4
86
Put Procedure
1. A put procedure must be defined in the qinit structure for every queue in a stream to pass messages
between the STREAMS components.
2. A put procedure does not have any user context, so it must not sleep and must not call any functions that
call sleep().
3. The put procedure cannot access the information in the u_area of a process as no user context is
associated with it.
4. A put procedure must use the streams utility putq() to enqueue a message on its own queue to maintain
the consistency of the queue structure. The put procedure of a queue must only call putq(), if the queue
has a service procedure associated with it.
5. The putq() does not process M_FLUSH messages. Therefore if putq() is specified as the put procedure for
a queue in its qinit structure, then the service procedure defined for the same queue must process the
M_FLUSH messages.
6. When a modules/driver’s put procedure needs to pass the message to its next component the streams
utility putnext() must be used. The putq() must not be used to place the message on the next
components queue directly.
7. Processing data messages by both put and service procedures could lead to messages going out of
sequence. The put procedure should check if any data messages were queued before processing the
current message.
8. Return codes can be sent with M_IOCACK, M_IOCNAK and M_ERROR messages by a put procedure.
9. Processing too many function calls with the put procedure could lead to an interrupt stack overflow. To
avoid such a case, switch to service procedure processing whenever appropriate to switch to a different
stack.
10. Appropriate synchronization should be provided for data structures in a module/driver when both the put
and service procedures use them.
11. It is strongly recommended that put procedures not place the high priority messages on the queue.
Service Procedure
1. A service procedure does not have any user context, so it must not sleep() and must not call any
functions that call sleep().
2. The service procedure cannot access the information in the u_area of a process as no user context is
associated with it.
3. If flow control is desired, a service procedure must be defined. The canput() utilities should be used by
service procedures before doing a putnext() to honor flow control.
4. The service procedure must use the streams utility getq() to remove a message from its message queue
to maintain the flow control mechanism.
5. The service procedure should process all the messages on its queue. The only exception being if the
stream ahead is flow controlled (i.e., canput() fails) or if some error condition (for example, memory
allocation failure) is encountered. Adherence to this rule is the only guarantee that STREAMS will
schedule the service procedure to execute when necessary and to ensure that the flow control mechanism
does not fail.
If a service procedure is written to exit for other reasons, than the driver/module developer must take
explicit steps to ensure that the service procedure is reenabled.