home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / ISP / bind.4.8.3.lzh / BIND483 / RES / select.c.old < prev    next >
Text File  |  1994-09-22  |  6KB  |  194 lines

  1.  /* ------------------------------------------------------------------- *
  2.  |
  3.  | OS9Lib:  select()
  4.  |
  5.  |
  6.  |     Copyright (c) 1988 by Wolfgang Ocker, Puchheim,
  7.  |                           Ulli Dessauer, Germering and
  8.  |                           Reimer Mellin, Muenchen
  9.  |                           (W-Germany)
  10.  |
  11.  |  This  programm can  be  copied and  distributed freely  for any
  12.  |  non-commercial  purposes.   It can only  be  incorporated  into
  13.  |  commercial software with the written permission of the authors.
  14.  |
  15.  |  If you should modify this program, the authors would appreciate
  16.  |  a notice about the changes. Please send a (context) diff or the
  17.  |  complete source to:
  18.  * ----------------------------------------------------------------- */
  19.  
  20. #include <time.h>
  21. #include <stdio.h>
  22. #include <errno.h>
  23. #include <signal.h>
  24.  
  25. #define READY_SIG   (1999)
  26. #define ALM_SIG     (2000)
  27.  
  28. /*#define SEL_PRT_FLG*/
  29.  
  30. static int sigarrived = 0;      /* READY_SIG occurred ? */
  31. static int pid, clk_tck = 0;
  32. extern int ev_id;
  33.  
  34. static void sighand(sig)
  35. int sig;
  36. {
  37.    sigarrived = sig;
  38. }
  39.  
  40. /*
  41.  * S E L E C T
  42.  *  returns # of fd's ready for read/write/network, -1 if interrupted or
  43.  *  a bad fd was encountered or 0 if none fd is ready for the action.
  44.  */
  45.  
  46. int select(fds, rdp, wrp, exp, timeout)
  47. int fds, *wrp;
  48. register int *rdp, *exp;
  49. register struct timeval *timeout;
  50. {
  51.    register int i;
  52.    register unsigned int shift;
  53.    int tout;
  54.    register int rd, wr, ex;
  55.    int leave = 0;
  56.    int tmp = 0;
  57.    int signaled = 0;
  58.    int alm_id, pollflag;
  59.  
  60.    int ev_value = 0;
  61.  
  62.    if ( clk_tck == 0 ) {
  63.       pid = getpid();
  64.       clk_tck = CLK_TCK;
  65.    }
  66.    signal(READY_SIG, sighand);
  67.    signal(ALM_SIG, sighand);
  68.  
  69.    /* Calculate the timeout in Ticks .. add one tick (for the polling case)
  70.     * if timeout == (struct timeval *)0 set to 0, */
  71.    pollflag = timeout && (timeout->tv_sec == 0) && (timeout->tv_usec == 0);
  72.    tout = timeout ? (1 + timeout->tv_sec * clk_tck + (timeout->tv_usec *
  73.                                                     clk_tck) / 1000000) : 0;
  74.    /* set pointers to dummy value if unspecified */
  75.    if (rdp == 0)
  76.       rdp = &tmp;
  77.    if (wrp == 0)
  78.       wrp = &tmp;
  79.    if (exp == 0)
  80.       exp = &tmp;
  81.  
  82.    rd = wr = ex = 0;
  83.    sigarrived = 0;
  84.  
  85.    do {
  86.       shift = (1 << (fds - 1));
  87.       for (i = fds - 1; i >= 0; shift >>= 1, --i) {
  88.          /* if data is available for reading mark it as ready */
  89.          if (*rdp & shift && (_gs_rdy(i) > 0 || (errno == E_UNKSVC))) {
  90.             rd |= shift;
  91.             leave++;
  92.          }
  93.          /* if network condition is ready mark it as ready */
  94.          if (*exp & shift && (ev_value > 0)) {
  95.             ex |= shift;
  96.             leave++;
  97.          }
  98.       }
  99.  
  100. #ifdef SEL_PRT_FLG
  101.       fprintf(stderr, "====== select(%d): leave %d ev_id %u\n", pid, leave, ev_id);
  102. #endif
  103.  
  104.       if (pollflag || leave)
  105.          break;
  106.  
  107.       /* prepare for waiting .., block signals */
  108.       sigmask(1);
  109.       shift = (1 << (fds - 1));
  110.       for (i = fds - 1; i >= 0; shift >>= 1, --i) {
  111.          if (*rdp & shift) {
  112.             _ss_ssig(i, READY_SIG);
  113.             signaled |= shift;
  114.          }
  115.          if (*exp & shift)
  116.             signaled |= shift;
  117.       }
  118.       /* wait specified timeout (implicit unblock signal !!) */
  119.       if (*exp == 0) {
  120.  
  121. #ifdef SEL_PRT_FLG
  122.          fprintf(stderr, "====== select(%d): about to sleep %d ticks\n", pid, tout);
  123. #endif
  124.          i = tsleep(tout);
  125.  
  126. #ifdef SEL_PRT_FLG
  127.          fprintf(stderr, "====== select(%d): signal %d\n", pid, sigarrived);
  128. #endif
  129.  
  130. /* if we are interrupted, or timed-out get out of here */
  131.  
  132.          if (sigarrived == 0) {
  133.             if (i < 0) {        /* error in tsleep, no clock */
  134.                leave = -1;
  135.             } else if (i == 0) {/* no ticks left */
  136.                if (tout == 0) { /* but..infinite timout was requested */
  137.                   leave = -1;
  138.                   errno = EINTR;
  139.                } else {         /* must have timed out */
  140.                   leave = 0;
  141.                   break;
  142.                }
  143.             } else {            /* ticks remain ? pretend interrupt */
  144.                leave = -1;
  145.                errno = EINTR;
  146.             }
  147.             break;
  148.          }
  149.          /* signal arrived, go check data */
  150.       } else {                  /* exp != 0, wait also on network */
  151.          if (tout < 2)
  152.             tout = 2;
  153.  
  154. #ifdef SEL_PRT_FLG
  155.          fprintf(stderr, "====== select(%d): about to wait %d ticks\n", pid, tout);
  156. #endif
  157.          alm_id = alm_set(ALM_SIG, tout);
  158.          ev_value = _ev_wait(ev_id, 1, 32767);
  159.          sigmask(0);
  160.  
  161. #ifdef SEL_PRT_FLG
  162.          fprintf(stderr, "====== select(%d): signal %d event %d\n", \
  163.                  pid, sigarrived, ev_value);
  164. #endif
  165.          alm_delete(alm_id);
  166.          if (sigarrived == ALM_SIG)         /* time out, leave = 0 */
  167.             break;
  168.          else if (sigarrived == READY_SIG)  /* non-net data present, check */
  169.             continue;
  170.          else if ( ev_value > 0 ) {         /* net data ready */
  171.             leave++;
  172.             ex = *exp;
  173.          } else {                           /* we were interrupted ... */
  174.             leave = -1;
  175.             errno = EINTR;
  176.          }
  177.       }                         /* *exp != 0, end of wait on network */
  178.    } while ( leave == 0 );
  179.  
  180.    /* reset signals .. */
  181.    shift = (1 << (fds - 1));
  182.    for (i = fds - 1; i >= 0; shift >>= 1, --i)
  183.       if (signaled & shift)
  184.          _ss_rel(i);
  185.    /* get results.. */
  186.    *rdp = rd;
  187.    *wrp = wr;
  188.    *exp = ex;
  189. #ifdef SEL_PRT_FLG
  190.    fprintf(stderr, "====== select(%d): results %x %x\n", pid, rd, ex);
  191. #endif
  192.    return leave;
  193. }
  194.