The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Интерактивная система просмотра системных руководств (man-ов)

 ТемаНаборКатегория 
 
 [Cписок руководств | Печать]

bufcall (9)
  • >> bufcall (9) ( Solaris man: Ядро )
  •  

    NAME

    bufcall - call a function when a buffer becomes available
     
    

    SYNOPSIS

    #include <sys/types.h>
    #include <sys/stream.h>
    
    
    
    bufcall_id_t bufcall(size_t size, uint_t pri, void *funcvoid *arg, 
       void *arg);
    

     

    INTERFACE LEVEL

    Architecture independent level 1 (DDI/DKI).  

    PARAMETERS

    size

    Number of bytes required for the buffer.

    pri

    Priority of the allocb(9F) allocation request (not used).

    func

    Function or driver routine to be called when a buffer becomes available.

    arg

    Argument to the function to be called when a buffer becomes available.

     

    DESCRIPTION

    The bufcall() function serves as a timeout(9F) call of indeterminate length. When a buffer allocation request fails, bufcall() can be used to schedule the routine func, to be called with the argument arg when a buffer becomes available. func may call allocb() or it may do something else.  

    RETURN VALUES

    If successful, bufcall() returns a bufcall ID that can be used in a call to unbufcall() to cancel the request. If the bufcall() scheduling fails, func is never called and 0 is returned.  

    CONTEXT

    The bufcall() function can be called from user, interrupt, or kernel context.  

    EXAMPLES

    Example 1 Calling a function when a buffer becomes available:

    The purpose of this srv(9E) service routine is to add a header to all M_DATA messages. Service routines must process all messages on their queues before returning, or arrange to be rescheduled

    While there are messages to be processed (line 13), check to see if it is a high priority message or a normal priority message that can be sent on (line 14). Normal priority message that cannot be sent are put back on the message queue (line 34). If the message was a high priority one, or if it was normal priority and canputnext(9F) succeeded, then send all but M_DATA messages to the next module with putnext(9F) (line 16).

    For M_DATA messages, try to allocate a buffer large enough to hold the header (line 18). If no such buffer is available, the service routine must be rescheduled for a time when a buffer is available. The original message is put back on the queue (line 20) and bufcall (line 21) is used to attempt the rescheduling. It will succeed if the rescheduling succeeds, indicating that qenable will be called subsequently with the argument q once a buffer of the specified size (sizeof (struct hdr)) becomes available. If it does, qenable(9F) will put q on the list of queues to have their service routines called. If bufcall() fails, timeout(9F) (line 22) is used to try again in about a half second.

    If the buffer allocation was successful, initialize the header (lines 25-28), make the message type M_PROTO (line 29), link the M_DATA message to it (line 30), and pass it on (line 31).

    Note that this example ignores the bookkeeping needed to handle bufcall() and timeout(9F) cancellation for ones that are still outstanding at close time.

     1  struct hdr {
    2     unsigned int h_size;
    3     int          h_version;
    4  };
    5
    6  void xxxsrv(q)
    7     queue_t *q;
    8  {
    9     mblk_t *bp;
    10     mblk_t *mp;
    11     struct hdr *hp;
    12
    13     while ((mp = getq(q)) != NULL) { /* get next message */
    14         if (mp->b_datap->db_type >= QPCTL || /* if high priority */
                    canputnext(q)) {        /* normal & can be passed */
    15            if (mp->b_datap->db_type != M_DATA)
    16                 putnext(q, mp);      /* send all but M_DATA */
    17            else {
    18                bp = allocb(sizeof(struct hdr), BPRI_LO);
    19                if (bp == NULL) {     /* if unsuccessful */
    20                     putbq(q, mp);    /* put it back */
    21                     if (!bufcall(sizeof(struct hdr), BPRI_LO,
                              qenable, q))  /* try to reschedule */
    22                         timeout(qenable, q, drv_usectohz(500000));
    23                        return (0);
    24                 }
    25                 hp = (struct hdr *)bp->b_wptr;
    26                 hp->h_size = msgdsize(mp);   /* initialize header */
    27                 hp->h_version = 1;
    28                 bp->b_wptr += sizeof(struct hdr);
    29                 bp->b_datap->db_type = M_PROTO;/* make M_PROTO  */
    30                 bp->b_cont = mp;     /* link it */
    31                 putnext(q, bp);      /* pass it on */
    32            }
    33         } else {     /* normal priority, canputnext failed */
    34           putbq(q, mp);      /* put back on the message queue */
    35           return (0);
    36         }
    37        }
            return (0);
    38  }
    

     

    SEE ALSO

    srv(9E), allocb(9F), canputnext(9F), esballoc(9F), esbbcall(9F), putnext(9F), qenable(9F), testb(9F), timeout(9F), unbufcall(9F)

    Writing Device Drivers

    STREAMS Programming Guide  

    WARNINGS

    Even when func is called by bufcall(), allocb(9F) can fail if another module or driver had allocated the memory before func was able to call allocb(9F).


     

    Index

    NAME
    SYNOPSIS
    INTERFACE LEVEL
    PARAMETERS
    DESCRIPTION
    RETURN VALUES
    CONTEXT
    EXAMPLES
    SEE ALSO
    WARNINGS


    Поиск по тексту MAN-ов: 




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру