STREAMS Programming Guide

Exit Print View

Updated: July 2014
 
 

Queue service Procedure

A queue's service procedure is invoked to process messages on the queue. It removes successive messages from the queue, processes them, and calls the put procedure of the next module in the stream to give the processed message to the next queue.

The service procedure is optional. A module or driver can use a service procedure for the following reasons:

  • Streams flow control is implemented by service procedures. If the next component on the stream has been flow controlled, the put procedure can queue the message. (See Flow Control in Service Procedures in Chapter 7, STREAMS Framework – Kernel Level for more on flow control.)

  • Resource allocation recovery. If a put or service procedure cannot allocate a resource, such as memory, the message is usually queued to process later.

  • A device driver can queue a message and get out of interrupt context.

  • To combine multiple messages into larger messages.

The service procedure is invoked by the STREAMS scheduler. A STREAMS service procedure is scheduled to run if:

  • The queue is not disabled (noenable(9F)) and the message being queued is either the first message on the queue, or a priority band message.

  • The message being queued (putq(9F) or putbq(9F)) is a high-priority message,

  • The queue has been back-enabled because flow control has been relieved,

  • The queue has been explicitly enabled (qenable(9F)).

A service procedure usually processes all messages on its queue (getq(9F)) or takes appropriate action to ensure it is re-enabled (qenable(9F)) at a later time. Figure 7–11 shows the flow of a service procedure.


Caution

Caution  - High-priority messages (db_type and MSG_HIPRI) must never be placed back on a service queue (putbq(9F)). Placing these messages in a service queue can cause an infinite loop.


Put procedures must never call putq, putbq, or qenable if the module does not have a service procedure.

Figure 7-11  Flow of service Procedure

image:Flow diagram shows how the service procedure processes messages.

The following example shows the stub code for a module service procedure.

Example 7-4  Module service Procedure
/*example of a module service procedure */
int
xxrsrv(queue_t *q)
{
		mblk_t *mp;
   /*
    * While there are still messages on our service queue
    */
		while ((mp = getq(q) != NULL) {
			/*
       * We check for high priority messages, but
       * none is ever seen since the put procedure
       * never queues them.
       * If the next module is not flow controlled, then
       */
      if (mp->b_datap->db_type >= QPCTL || (canputnext (q)) {
				/*
				 * process message
				 */
				.
				.
				.
				putnext (q, mp);
			} else {
				/*
          * put message back on service queue
          */
				putbq(q,mp);
				break;
			}
		}
		return (0);
}