1dupb(9F) Kernel Functions for Drivers dupb(9F)
2
3
4
6 dupb - duplicate a message block descriptor
7
9 #include <sys/stream.h>
10
11
12
13 mblk_t *dupb(mblk_t *bp);
14
15
17 Architecture independent level 1 (DDI/DKI).
18
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
35 bp Pointer to the message block to be duplicated. mblk_t is an
36 instance of the msgb(9S) structure.
37
38
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
46 dupb() can be called from user, kernel, or interrupt context.
47
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
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)