insq(D3DK) —
.IX \f4insq\fP(D3DK)
NAME
insq − insert a message into a queue
SYNOPSIS
#include <sys/stream.h>
int insq(queue_t ∗q, mblk_t ∗emp, mblk_t ∗nmp);
ARGUMENTS
qPointer to the queue containing message emp.
empPointer to the existing message before which the new message is to be inserted.
nmpPointer to the new message to be inserted.
DESCRIPTION
insq inserts a message into a queue. The message to be inserted, nmp, is placed in the queue pointed to by q, immediately before the message, emp. If emp is NULL, the new message is placed at the end of the queue. All flow control parameters are updated. The service procedure is scheduled to run unless disabled by a previous call to noenable(D3DK).
Messages are ordered in the queue based on their priority, as described in srv(D2DK). If an attempt is made to insert a message out of order in the queue, then nmp is not enqueued.
RETURN VALUE
If nmp was successfully enqueued, insq returns 1. Otherwise, insq returns 0.
LEVEL
Base or Interrupt.
NOTES
Does not sleep.
Driver-defined basic locks, read/write locks, and sleep locks may be held across calls to this function.
The insertion can fail if there is not enough memory to allocate the accounting data structures used with messages whose priority bands are greater than zero.
If emp is non-NULL, it must point to a message in the queue pointed to by q, or a system panic could result.
SEE ALSO
srv(D2DK), getq(D3DK), putbq(D3DK), putq(D3DK), rmvq(D3DK),
EXAMPLE
This routine illustrates the use of insq to insert a message into the middle of a queue. This routine can be used to strip all the M_PROTO headers off all messages on a queue. First, we freeze the stream (line 7) so the state of the queue does not change while we are searching it. Then we traverse the list of messages on the queue, looking for M_PROTO messages (line 11). When one is found, we remove it from the queue using rmvq(D3DK) (line 12). If there is no data portion of the message (line 13), we free the entire message using freemsg(D3DK). Otherwise, for every M_PROTO message block in the message, we strip the M_PROTO block off using unlinkb(D3DK) (line 17) and free the message block using freeb(D3DK). When the header has been stripped, the data portion of the message is inserted back into the queue where it was originally found (line 21). Finally, when we are done searching the queue, we unfreeze the stream (line 26).
1 void
2 striproto(q)
3queue_t ∗q;
4 {
5register mblk_t ∗emp, ∗nmp, ∗mp;
6pl_t pl;
8mp = q->q_first;
9while (mp) {
10emp = mp->b_next;
11if (mp->b_datap->db_type == M_PROTO) {
12rmvq(q, mp);
13if (msgdsize(mp) == 0) {
14freemsg(mp);
15} else {
16while (mp->b_datap->db_type == M_PROTO) {
17nmp = unlinkb(mp);
18freeb(mp);
19mp = nmp;
20}
21insq(q, emp, mp);
22}
23}
24mp = emp;
25}
27 }
.IX \f4freezestr\fP(D3DK), example
.IX \f4insq\fP(D3DK), example
.IX \f4msgdsize\fP(D3DK), example
.IX \f4rmvq\fP(D3DK), example
.IX \f4unfreezestr\fP(D3DK), example
.IX \f4unlinkb\fP(D3DK), example
DDI/DKI — STREAMS