DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
SVR5 and SCO OpenServer

put(D2str)


put -- receive messages from the preceding queue

Syntax

   #include <sys/types.h>
   #include <sys/stream.h>
   #include <sys/stropts.h>
   #include <sys/ddi.h>
   

int prefixrput(queue_t *q, mblk_t *mp); /* read side */

int prefixwput(queue_t *q, mblk_t *mp); /* write side */

Description

The driver's put( ) entry point routines coordinate the passing of messages from one queue to the next in a stream. The put( ) routine is called by the preceding component (module, driver, or stream head) in the stream. put( ) routines are designated ``write'' or ``read'' depending on the direction of message flow.

Arguments


q
Pointer to the queue.

mp
Pointer to the message block.

Return values

Ignored

Usage

This entry point is required in all STREAMS drivers and modules.

Both modules and drivers must have write put routines. Modules must have read put routines, but drivers don't really need them because their interrupt handler can do the work intended for the read put routine. A message is passed to the put routine. If immediate processing is desired, the put routine can process the message, or it can enqueue it so that the srv(D2str) service routine can process it later.

The put routine must do at least one of the following when it receives a message:

Typically, the put routine switches on the message type, which is contained in mp->b_datap->db_type, taking different actions depending on the message type. For example, a put routine might process high priority messages and enqueue normal messages.

The putq function can be used as a module's put routine when no special processing is required and all messages are to be enqueued for the service routine.

Drivers and modules usually handle queue flushing in their put routines, although it can be done in the service routine.

Synchronization constraints

Interrupt context

Multithreaded drivers must not hold locks when passing messages to other queues in the stream.

With multithreaded drivers, multiple copies of the same put routine for a given queue, as well as the service routine for the queue, can be running concurrently. Drivers and modules are responsible for synchronizing access to their own private data structures accordingly.

Hardware applicability

All

Version applicability

ddi: 1, 2, 3, 4, 5, 5mp, 6, 6mp, 7, 7mp, 7.1, 7.1mp, 8, 8mp

oddi: 1, 2, 2mp, 3, 3mp, 4, 4mp, 5, 5mp

References

datab(D4str), flushband(D3str), flushq(D3str), msgb(D4str), putctl(D3str), putctl1(D3str), putnext(D3str), putq(D3str), qreply(D3str), queue(D4str), srv(D2str), uwput(D2mdi)

Examples

The canonical flushing algorithm for driver write put routines is as follows:

	queue_t *q;	/* the write queue */
	if (*mp->b_rptr & FLUSHBAND) { /* if driver recognizes bands */
		if (*mp->b_rptr & FLUSHW) {
			flushband(q, FLUSHDATA, *(mp->b_rptr + 1));
			*mp->b_rptr &= ~FLUSHW;
		}
		if (*mp->b_rptr & FLUSHR) {
			flushband(RD(q), FLUSHDATA, *(mp->b_rptr + 1));
			qreply(q, mp);
		} else {
			freemsg(mp);
		}
	} else {
		if (*mp->b_rptr & FLUSHW) {
			flushq(q, FLUSHDATA);
			*mp->b_rptr &= ~FLUSHW;
		}
		if (*mp->b_rptr & FLUSHR) {
			flushq(RD(q), FLUSHDATA);
			qreply(q, mp);
		} else {
			freemsg(mp);
		}
	}

The canonical flushing algorithm for module write put routines is as follows:

	queue_t *q;	/* the write queue */
	if (*mp->b_rptr & FLUSHBAND) { /* if module recognizes bands */
		if (*mp->b_rptr & FLUSHW)
			flushband(q, FLUSHDATA, *(mp->b_rptr + 1));
		if (*mp->b_rptr & FLUSHR)
			flushband(RD(q), FLUSHDATA, *(mp->b_rptr + 1));
	} else {
		if (*mp->b_rptr & FLUSHW)
			flushq(q, FLUSHDATA);
		if (*mp->b_rptr & FLUSHR)
			flushq(RD(q), FLUSHDATA);
	}
	if (!SAMESTR(q)) {
		switch (*mp->b_rptr & FLUSHRW) {
		case FLUSHR:
			*mp->b_rptr = (*mp->b_rptr & ~FLUSHR) | FLUSHW;
			break;
		case FLUSHW:
			*mp->b_rptr = (*mp->b_rptr & ~FLUSHW) | FLUSHR;
			break;
		}
	}
	putnext(q, mp);

The algorithms for the read side are similar. In both examples, the FLUSHBAND flag need only be checked if the driver or module cares about priority bands.

Drivers and modules should not call put routines directly.

Drivers should free any messages they do not recognize.

Modules should pass on any messages they do not recognize.

Drivers should fail any unrecognized M_IOCTL(D7str) messages by converting them into M_IOCNAK(D7str) messages and sending them upstream.

Modules should pass on any unrecognized M_IOCTL messages.


19 June 2005
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005