QWAIT(9F) Kernel Functions for Drivers QWAIT(9F)
NAME
qwait, qwait_sig - STREAMS wait routines
SYNOPSIS
#include <sys/stream.h>
#include <sys/ddi.h>
void qwait(
queue_t *q);
int qwait_sig(
queue_t *q);
INTERFACE LEVEL
illumos DDI specific (illumos DDI).
PARAMETERS
qp Pointer to the queue that is being opened or closed.
DESCRIPTION
qwait() and
qwait_sig() are used to wait for a message to arrive to
the
put(9E) or
srv(9E) procedures.
qwait() and
qwait_sig() can also
be used to wait for
qbufcall(9F) or
qtimeout(9F) callback procedures
to execute. These routines can be used in the
open(9E) and
close(9E) procedures in a STREAMS driver or module.
The thread that calls
close() does not necessarily have the ability
to receive signals, particularly when called by
exit(2). In this
case,
qwait_sig() behaves exactly as
qwait(). Driver writers may use
ddi_can_receive_sig(9F) to determine when this is the case, and, if
so, arrange some means to avoid blocking indefinitely (for example,
by using
qtimeout(9F).
qwait() and
qwait_sig() atomically exit the inner and outer
perimeters associated with the queue, and wait for a thread to leave
the module's
put(9E),
srv(9E), or
qbufcall(9F) /
qtimeout(9F) callback procedures. Upon return they re-enter the inner and outer
perimeters.
This can be viewed as there being an implicit wakeup when a thread
leaves a
put(9E) or
srv(9E) procedure or after a
qtimeout(9F) or
qbufcall(9F) callback procedure has been run in the same perimeter.
qprocson(9F) must be called before calling
qwait() or
qwait_sig().
qwait() is not interrupted by a signal, whereas
qwait_sig() is
interrupted by a signal.
qwait_sig() normally returns non-zero, and
returns zero when the waiting was interrupted by a signal.
qwait() and
qwait_sig() are similar to
cv_wait() and
cv_wait_sig() except that the mutex is replaced by the inner and outer perimeters
and the signalling is implicit when a thread leaves the inner
perimeter. See
condvar(9F).
RETURN VALUES
0 For
qwait_sig(), indicates that the condition was not
necessarily signaled, and the function returned because a signal
was pending.
CONTEXT
These functions can only be called from an
open(9E) or
close(9E) routine.
EXAMPLES
Example 1: Using qwait()
The open routine sends down a
T_INFO_REQ message and waits for the
T_INFO_ACK. The arrival of the
T_INFO_ACK is recorded by resetting a
flag in the unit structure (
WAIT_INFO_ACK). The example assumes that
the module is
D_MTQPAIR or
D_MTPERMOD.
xxopen(qp, ...)
queue_t *qp;
{
struct xxdata *xx;
/* Allocate xxdata structure */
qprocson(qp);
/* Format T_INFO_ACK in mp */
putnext(qp, mp);
xx->xx_flags |= WAIT_INFO_ACK;
while (xx->xx_flags & WAIT_INFO_ACK)
qwait(qp);
return (0);
}
xxrput(qp, mp)
queue_t *qp;
mblk_t *mp;
{
struct xxdata *xx = (struct xxdata *)q->q_ptr;
...
case T_INFO_ACK:
if (xx->xx_flags & WAIT_INFO_ACK) {
/* Record information from info ack */
xx->xx_flags &= ~WAIT_INFO_ACK;
freemsg(mp);
return;
}
...
}
SEE ALSO
close(9E),
open(9E),
put(9E),
srv(9E),
condvar(9F),
ddi_can_receive_sig(9F),
mt-streams(9F),
qbufcall(9F),
qprocson(9F),
qtimeout(9F) STREAMS Programming Guide Writing Device Drivers December 15, 2003 QWAIT(9F)