Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ select(K) — OpenDesktop Software Development System 1.0.0d

Media Vault

Software Library

Restoration Projects

Artifacts Sought



     SELECT(K)                 UNIX System V                 SELECT(K)



     Name
          select: selsuccess, selfailure, selwakeup - kernel routines
          supporting select(S)

     Syntax
          #include "sys/select.h"

          void selsuccess()

          void selfailure()

          void selwakeup(proc-ptr, flags)
          struct proc *proc-ptr;
          char flags;

     Description
          The select(S) system call code sends a unique I/O control
          command to the driver to ask whether or not a condition is
          satisfied for reading, writing, or exceptional
          circumstances. The mode argument to the xxioctl call
          indicates the condition being selected, and has these values
          which are defined in sys/select.h: SELREAD, SELWRITE, and
          SELEXCEPT.  All drivers that support select must implement
          the IOC_SELECT ioctl with code similar to that displayed in
          the example section in this manual page.

          Drivers supporting select(S) must include global
          declarations like the following:

          #include "sys/select.h"
          extern int selwait;
          struct xx_selstr
          {
                  struct proc *read;
                  struct proc *write;
                  struct proc *except;
                  char flags;
          }
          xxselstr[NUM_MINOR_DEVS];

          A driver uses selfailure to indicate that the condition
          which the user has selected is not true, and the process
          should block.

          A driver uses selsuccess to indicate that the condition
          which the user has selected is true, and the process should
          not block.

          A driver uses selwakeup to indicate that the condition the
          user selected which was not initially satisfied, is now
          true.  The process should now be awakened.

     Parameters
          procp is a pointer to a process table entry which is found
          in the xxselstr data structure.  Each time a process selects
          a condition that is not immediately satisfied, a pointer to
          the process is stored in the data structure. This pointer is
          passed to the select(S) system call by the selwakeup call.

          flags is a byte used to indicating if multiple processes are
          colliding by selecting the same condition. Whenever more
          than one process selects a condition, the driver must set
          the correct collision bit. The three bits defined in
          sys/select.h are: READ_COLLISION, WRITE_COLLISION, and
          EXCEPT_COLLISION, for selecting for reading, writing, and
          exceptional conditions, respectively.

     Examples
          In the first example, a process issues the select(S) system
          call (read case only): Note that the examples can be
          replicated identically substituting write and except for all
          occurrences of read.

          /*
          * This routine from driver xx
          * handles a select for read request.
          * Note all requests come from
          * the select system call individually.
          */

          xxioctl(dev, cmd, mode, arg)
          dev_t dev;
          int cmd, mode, arg;
          {
                  ...
                  if ( cmd == IOC_SELECT )
                          {
                          switch (mode)
                          {
                          case SELREAD:   xx_selread(dev);
                          break;

                          /*
                          * likewise for SELWRITE and SELEXCEPT
                          */
                          }
                          return;
                          }
                  ...

          /*
          * Normal ioctl processing
          */

          }

          xx_selread(dev)
          dev_t dev;
          {
                  extern void selsuccess();
                  extern void selfailure();
                  struct proc *procp;
                  struct xx_selstr *ptr = &xxselstr[dev];

                  if ( xx_condition_is_satisfied_for_read[dev] )
                  {
                          selsuccess();
                          return;
                  }

                  /*
                   * Condition is unsatisfied; process will block.
                   */

                  procp = ptr->read;
                  if ( procp && procp->p_wchan == (char*) &selwait )
                          ptr->flags |= READ_COLLISION;
                  else
                          ptr->read = u.u_procp;
                  selfailure();
          }

          In the next example, the process has selected a condition
          and is blocked.  Then, the condition becomes satisfied (read
          case handled):

          xxintr(level)
          {
                  ...

                  /*
                  * Driver first notices that the condition is now
                  * satisfied and computes minor dev
                  */

                  xxwakeread(dev);
                  ...
          }

          xxwakeread(dev)
          dev_t dev;
          {
                  struct xx_selstr *ptr = &xxselstr[dev];

                  /*
                  * If a proc has selected the condition, awaken it.
                  */

                  if ( ptr->read )
                  {
                          selwakeup(ptr->read, ptr->flags
                                          & READ_COLLISION);
                          ptr->read = (struct proc *) NULL;
                          ptr->flags &= ~READ_COLLISION;
                  }
          }

                                                      (printed 7/6/89)



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