Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ put(D2) — UnixWare 2.01

Media Vault

Software Library

Restoration Projects

Artifacts Sought






       put(D2)                                                      put(D2)


       NAME
             put - receive messages from the preceding queue

       SYNOPSIS
             #include <sys/types.h>
             #include <sys/stream.h>
             #include <sys/stropts.h>
             #include <sys/ddi.h>
             int prefixrput(queue_t *q, mblk_t *mp);  /* read side */
             int prefixwput(queue_t *q, mblk_t *mp);  /* write side */

          Arguments
             q     Pointer to the queue.

             mp    Pointer to the message block.

       DESCRIPTION
             The primary task of the put routine is to coordinate the
             passing of messages from one queue to the next in a stream.
             The put routine is called by the preceding component (module,
             driver, or stream head) in the stream.  put routines are
             designated ``write'' or ``read'' depending on the direction of
             message flow.

          Return Values
             Ignored

       USAGE
             This entry point is required in all STREAMS drivers and
             modules.

             Both modules and drivers must have write put routines.
             Modules must have read put routines, but drivers don't really
             need them because their interrupt handler can do the work
             intended for the read put routine.  A message is passed to the
             put routine.  If immediate processing is desired, the put
             routine can process the message, or it can enqueue it so that
             the service routine [see srv(D2)] can process it later.

             The put routine must do at least one of the following when it
             receives a message:

                   pass the message to the next component in the stream by
                   calling the putnext(D3) function




                           Copyright 1994 Novell, Inc.               Page 1













      put(D2)                                                      put(D2)


                  process the message, if immediate processing is required
                  (for example, high priority messages)

                  enqueue the message with the putq(D3) function for
                  deferred processing by the service routine

            Typically, the put routine will switch on the message type,
            which is contained in mp->b_datap->db_type, taking different
            actions depending on the message type.  For example, a put
            routine might process high priority messages and enqueue
            normal messages.

            The putq function can be used as a module's put routine when
            no special processing is required and all messages are to be
            enqueued for the service routine.

            Although it can be done in the service routine, drivers and
            modules usually handle queue flushing in their put routines.

            The canonical flushing algorithm for driver write put routines
            is as follows:
                  queue_t *q; /* the write queue */
                  if (*mp->b_rptr & FLUSHBAND) { /* if driver recognizes bands */
                        if (*mp->b_rptr & FLUSHW) {
                              flushband(q, FLUSHDATA, *(mp->b_rptr + 1));
                              *mp->b_rptr &= ~FLUSHW;
                        }
                        if (*mp->b_rptr & FLUSHR) {
                              flushband(RD(q), FLUSHDATA, *(mp->b_rptr + 1));
                              qreply(q, mp);
                        } else {
                              freemsg(mp);
                        }
                  } else {
                        if (*mp->b_rptr & FLUSHW) {
                              flushq(q, FLUSHDATA);
                              *mp->b_rptr &= ~FLUSHW;
                        }
                        if (*mp->b_rptr & FLUSHR) {
                              flushq(RD(q), FLUSHDATA);
                              qreply(q, mp);
                        } else {
                              freemsg(mp);
                        }
                  }



                          Copyright 1994 Novell, Inc.               Page 2













       put(D2)                                                      put(D2)


             The canonical flushing algorithm for module write put routines
             is as follows:
                   queue_t *q; /* the write queue */
                   if (*mp->b_rptr & FLUSHBAND) { /* if module recognizes bands */
                         if (*mp->b_rptr & FLUSHW)
                               flushband(q, FLUSHDATA, *(mp->b_rptr + 1));
                         if (*mp->b_rptr & FLUSHR)
                               flushband(RD(q), FLUSHDATA, *(mp->b_rptr + 1));
                   } else {
                         if (*mp->b_rptr & FLUSHW)
                               flushq(q, FLUSHDATA);
                         if (*mp->b_rptr & FLUSHR)
                               flushq(RD(q), FLUSHDATA);
                   }
                   if (!SAMESTR(q)) {
                         switch (*mp->b_rptr & FLUSHRW) {
                         case FLUSHR:
                               *mp->b_rptr = (*mp->b_rptr & ~FLUSHR) | FLUSHW;
                               break;
                         case FLUSHW:
                               *mp->b_rptr = (*mp->b_rptr & ~FLUSHW) | FLUSHR;
                               break;
                         }
                   }
                   putnext(q, mp);

             The algorithms for the read side are similar.  In both
             examples, the FLUSHBAND flag need only be checked if the
             driver or module cares about priority bands.

             Drivers and modules should not call put routines directly.

             Drivers should free any messages they do not recognize.

             Modules should pass on any messages they do not recognize.

             Drivers should fail any unrecognized M_IOCTL messages by
             converting them into M_IOCNAK messages and sending them
             upstream.

             Modules should pass on any unrecognized M_IOCTL messages.

          Synchronization Constraints
             put routines do not have user context and so may not call any
             function that sleeps.



                           Copyright 1994 Novell, Inc.               Page 3













      put(D2)                                                      put(D2)


            Multithreaded drivers must not hold locks when passing
            messages to other queues in the stream.

            With multithreaded drivers, multiple copies of the same put
            routine for a given queue, as well as the service routine for
            the queue, can be running concurrently.  Drivers and modules
            are responsible for synchronizing access to their own private
            data structures accordingly.

      REFERENCES
            datab(D4), flushband(D3), flushq(D3), msgb(D4), putctl(D3),
            putctl1(D3), putnext(D3), putq(D3), qreply(D3), queue(D4),
            srv(D2)

      NOTICES
         Portability
            All processors

         Applicability
            ddi: 1, 2, 3, 4, 5, 5mp, 6, 6mp, 7, 7mp




























                          Copyright 1994 Novell, Inc.               Page 4








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