Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

copyb(9F)

qbufcall(9F)

datab(9S)

msgb(9S)

dupb(9F)

NAME

dupb − duplicate a message block descriptor

SYNOPSIS

#include <sys/stream.h>
mblk_t ∗dupb(mblk_t ∗bp);

INTERFACE LEVEL

Architecture independent level 1 (DDI/DKI). 

ARGUMENTS

bp Pointer to the message block to be duplicated.  mblk_t is an instance of the msgb(9S) structure. 

DESCRIPTION

dupb() creates a new mblk_t structure (see msgb(9S)) to reference the message block pointed to by bp.

Unlike copyb(9F), dupb() does not copy the information in the dblk_t structure (see datab(9S)), but creates a new mblk_t structure to point to it. The reference count in the dblk_t structure (db_ref) is incremented.  The new mblk_t structure contains the same information as the original.  Note that b_rptr and b_wptr are copied from the bp.


















.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.




.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.











nbp=dupb(bp);



Before
After
db_base
db_ref (2)








db_base
db_ref (1)
bp






b_datap


b_rptr
b_wptr




b_datap


b_rptr
b_wptr




b_datap


b_rptr
b_wptr




nbp






















bp

RETURN VALUES

If successful, dupb() returns a pointer to the new message block.  A NULL pointer is returned if dupb() cannot allocate a new message block descriptor or if the db_ref field of the data block structure (see datab(9S)) has reached a maximum value (255). 

CONTEXT

dupb() can be called from user, kernel, or interrupt context. 

EXAMPLES

This srv(9E) (service) routine adds a header to all M_DATA messages before passing them along.  dupb(9F) is used instead of copyb(9F) because the contents of the header block are not changed. 

For each message on the queue, if it is a priority message, pass it along immediately (lines 10−11).  Otherwise, if it is anything other than an M_DATA message (line 12), and if it can be sent along (line 13), then do so (line 14).  Otherwise, put the message back on the queue and return (lines 16−17).  For all M_DATA messages, first check to see if the stream is flow-controlled (line 20).  If it is, put the message back on the queue and return (lines 37−38).  If it is not, the header block is duplicated (line 21). 

dupb() can fail either due to lack of resources or because the message block has already been duplicated 255 times.  In order to handle the latter case, the example calls copyb(9F) (line 22).  If copyb(9F) fails, it is due to buffer allocation failure.  In this case, qbufcall(9F) is used to initiate a callback (lines 30-31) if one is not already pending (lines 26-27). 

The callback function, xxxcallback(), clears the recorded qbufcall(9F) callback id and schedules the service procedure (lines 49-50).  Note that the close routine, xxxclose(), must cancel any outstanding qbufcall(9F) callback requests (lines 58-59). 

If dupb() or copyb(9F) succeed, link the M_DATA message to the new message block (line 34) and pass it along (line 35). 

 1  xxxsrv(q)
 2      queue_t ∗q;
 3  {
 4struct xx ∗xx = (struct xx ∗)q->q_ptr;
 5mblk_t ∗mp;
 6mblk_t ∗bp;
 7extern mblk_t ∗hdr;
 8
 9while ((mp = getq(q)) != NULL) {
10if (mp->b_datap->db_type >= QPCTL) {
11putnext(q, mp);
12} else if (mp->b_datap->db_type != M_DATA) {
13if (canputnext(q))
14putnext(q, mp);
15else {
16putbq(q, mp);
17return;
18}
19} else {/∗ M_DATA ∗/
20if (canputnext(q)) {
21if ((bp = dupb(hdr)) == NULL)
22bp = copyb(hdr);
23if (bp == NULL) {
24uint size = msgdsize(mp);
25putbq(q, mp);
26if (xx->xx_qbufcall_id) {
27/∗ qbufcall pending ∗/
28return;
29}
30xx->xx_qbufcall_id = qbufcall(q, size,
31BPRI_MED, xxxcallback, (long)q);
32return;
33}
34linkb(bp, mp);
35putnext(q, bp);
36} else {
37putbq(q, mp);
38return;
39}
40}
41}
42  }
 43void
44xxxcallback(q)
45queue_t ∗q;
46{
47struct xx ∗xx = (struct xx ∗)q->q_ptr;
48
49xx->xx_qbufcall_id = 0;
50qenable(q);
51}
 52xxxclose(q, cflag, crp)
53queue_t ∗q;
54int  cflag;
55cred_t ∗crp;
56{
57struct xx ∗xx = (struct xx ∗)q->q_ptr;
...
58if (xx->xx_qbufcall_id)
59qunbufcall(q, xx->xx_qbufcall_id);
...
60}

SEE ALSO

copyb(9F), qbufcall(9F), datab(9S), msgb(9S)

Writing Device Drivers
STREAMS Programming Guide

SunOS 5.5/x86  —  Last change: 25 Oct 1994

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026