1dupb(9F)                 Kernel Functions for Drivers                 dupb(9F)
2
3
4

NAME

6       dupb - duplicate a message block descriptor
7

SYNOPSIS

9       #include <sys/stream.h>
10
11
12
13       mblk_t *dupb(mblk_t *bp);
14
15

INTERFACE LEVEL

17       Architecture independent level 1 (DDI/DKI).
18

DESCRIPTION

20       dupb()  creates a new  mblk_t structure (see msgb(9S)) to reference the
21       message block pointed to by  bp.
22
23
24       Unlike  copyb(9F), dupb() does not copy the information in the   dblk_t
25       structure (see datab(9S)), but creates a new  mblk_t structure to point
26       to it. The reference count in the  dblk_t structure (db_ref) is  incre‐
27       mented.   The new mblk_t structure contains the same information as the
28       original.  Note that b_rptrand b_wptr are copied from the bp.
29
30       Printed copy or docs.sun.com shows a figure that  shows  a  new  mblk_t
31       structure  created,  with  the original and new bp both pointing to the
32       dblk_t structure, and db_ref incremented by one
33

PARAMETERS

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

RETURN VALUES

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

CONTEXT

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

EXAMPLES

49       Example 1 Using dupb()
50
51
52       This  srv(9E) (service) routine adds a header to  all  M_DATA  messages
53       before passing them along.   dupb is used instead of  copyb(9F) because
54       the contents of the header block are not changed.
55
56
57
58       For each message on the queue, if it is a  priority  message,  pass  it
59       along  immediately  (lines  10-11).  Otherwise, if it is anything other
60       than an  M_DATA message (line 12), and if it can be  sent  along  (line
61       13), then do so (line 14). Otherwise, put the message back on the queue
62       and return (lines 16-17). For all  M_DATA messages, first check to  see
63       if  the  stream is flow-controlled (line 20). If it is, put the message
64       back on the queue and return (lines 37-38).  If it is not,  the  header
65       block is duplicated (line 21).
66
67
68
69       dupb()  can fail either due to lack of resources or because the message
70       block has already been duplicated 255 times.  In order  to  handle  the
71       latter  case,  the  example  calls  copyb(9F)  (line 22).  If copyb(9F)
72       fails, it is due to buffer allocation failure.  In  this  case,   qbuf‐
73       call(9F)  is  used  to  initiate a callback (lines 30-31) if one is not
74       already pending (lines 26-27).
75
76
77
78       The callback function, xxxcallback(), clears the recorded  qbufcall(9F)
79       callback  id  and  schedules the service procedure (lines 49-50).  Note
80       that the close routine,  xxxclose(), must cancel any outstanding  qbuf‐
81       call(9F) callback requests (lines 58-59).
82
83
84
85       If   dupb()  or  copyb(9F) succeed, link the  M_DATA message to the new
86       message block (line 34)  and pass it along (line 35).
87
88
89                1  xxxsrv(q)
90               2      queue_t *q;
91               3  {
92               4   struct xx *xx = (struct xx *)q->q_ptr;
93               5   mblk_t *mp;
94               6   mblk_t *bp;
95               7   extern mblk_t *hdr;
96               8
97               9   while ((mp = getq(q)) != NULL) {
98              10        if (mp->b_datap->db_type >= QPCTL) {
99              11             putnext(q, mp);
100              12        } else if (mp->b_datap->db_type != M_DATA) {
101              13             if (canputnext(q))
102              14                  putnext(q, mp);
103              15             else {
104              16                  putbq(q, mp);
105              17                  return;
106              18             }
107              19        } else {  /* M_DATA */
108              20             if (canputnext(q)) {
109              21                  if ((bp = dupb(hdr)) == NULL)
110              22                       bp = copyb(hdr);
111              23                  if (bp == NULL) {
112              24                       size_t size = msgdsize(mp);
113              25                       putbq(q, mp);
114              26                       if (xx->xx_qbufcall_id) {
115              27                            /* qbufcall pending */
116              28                            return;
117              29                       }
118              30                       xx->xx_qbufcall_id = qbufcall(q, size,
119              31                            BPRI_MED, xxxcallback, (intptr_t)q);
120              32                       return;
121              33                  }
122              34                  linkb(bp, mp);
123              35                  putnext(q, bp);
124              36             } else {
125              37                  putbq(q, mp);
126              38                  return;
127              39             }
128              40        }
129              41   }
130              42  }
131              43   void
132              44   xxxcallback(q)
133              45        queue_t *q;
134              46   {
135              47        struct xx *xx = (struct xx *)q->q_ptr;
136              48
137              49        xx->xx_qbufcall_id = 0;
138              50        qenable(q);
139              51   }
140
141              52   xxxclose(q, cflag, crp)
142              53        queue_t *q;
143              54        int  cflag;
144              55        cred_t *crp;
145              56   {
146              57        struct xx *xx = (struct xx *)q->q_ptr;
147                        ...
148              58        if (xx->xx_qbufcall_id)
149              59             qunbufcall(q, xx->xx_qbufcall_id);
150                        ...
151              60   }
152
153

SEE ALSO

155       srv(9E), copyb(9F), qbufcall(9F), datab(9S), msgb(9S)
156
157
158       Writing Device Drivers STREAMS Programming Guide
159
160
161
162SunOS 5.11                        22 Mar 2002                         dupb(9F)
Impressum