dupb(9f) 맨 페이지 - 윈디하나의 솔라나라

개요

섹션
맨 페이지 이름
검색(S)

dupb(9f)

dupb(9F)                       Kernel Functions                       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).

DESCRIPTION
       The  dupb()  function  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  incre‐
       mented.  The  new mblk_t structure contains the same information as the
       original. Note that b_rptr and b_wptr are copied from the bp.


       The printed copy and the Oracle Technology Network version of this man‐
       ual page show a new mblk_t structure created, with the original and new
       bp both pointing to the dblk_t structure,  and  db_ref  incremented  by
       one..SH PARAMETERS

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


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
       Example 1 Using dupb()



       This  srv(9E)  (service)  routine  adds a header to all M_DATA messages
       before passing them along. dupb 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 qbuf‐
       call(9F) callback requests (lines 58-59).



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


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

         52   xxxclose(q, cflag, crp)
         53        queue_t *q;
         54        int  cflag;
         55        cred_t *crp;
         56   {
         57        struct xx *xx = (struct xx *)q->q_ptr;
                   ...
         58        if (xx->xx_qbufcall_id)
         59             qunbufcall(q, xx->xx_qbufcall_id);
                   ...
         60   }


SEE ALSO
       srv(9E), copyb(9F), qbufcall(9F), datab(9S), msgb(9S)


       Writing  Device  Drivers  in  Oracle  Solaris 11.4  STREAMS Programming
       Guide



Oracle Solaris 11.4               02 Nov 2017                         dupb(9F)
맨 페이지 내용의 저작권은 맨 페이지 작성자에게 있습니다.
RSS ATOM XHTML 5 CSS3