home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / LIB / select.c < prev    next >
C/C++ Source or Header  |  2009-11-06  |  4KB  |  139 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 <errno.h>
  22. #include <signal.h>
  23.  
  24. #define reg         register
  25. #define READY_SIG   (31)        /* tune this ... */
  26.  
  27. #define ONLYRDY     (1)         /* select only on reading */
  28.  
  29. static  char    sigarrived = 0; /* READY_SIG occured ? */
  30.  
  31. static  void
  32. sighand()
  33. {
  34.     sigarrived = 1;
  35. }
  36.  
  37. /*
  38.  * S E L E C T
  39.  *  returns # of fd's ready for read/write/exeption, -1 if interrupted or
  40.  *  a bad fd was encountered or 0 if none fd is ready for the action.
  41.  */
  42.  
  43. int
  44. select( fds, rdp, wrp, exp, timeout)
  45.     int fds;
  46. reg int *rdp, *wrp, *exp;
  47. struct  timeval *timeout;
  48. {
  49.     reg     int      i;
  50.     reg unsigned int shift;
  51.             int      tout;
  52.     reg     int      rd, wr, ex;
  53.             int      leave = 0;
  54.             int      tmp = 0;
  55.             int      signaled = 0;
  56.  
  57.  
  58.     signal( READY_SIG, sighand);
  59.  
  60.     /* Calculate the timeout in Ticks ..
  61.      * add one tick (for the polling case)
  62.      * if timeout == (struct timeval *)0 set to 0,
  63.      */
  64.     tout = timeout ? ( 1 + timeout->tv_sec * CLK_TCK + ( timeout->tv_usec *
  65.                        CLK_TCK) / 1000 ) : 0;
  66.     /* set pointers to dummy value if unspecified */
  67.     if( rdp == 0)
  68.         rdp = &tmp;
  69.     if( wrp == 0)
  70.         wrp = &tmp;
  71.     if( exp == 0)
  72.         exp = &tmp;
  73.  
  74.     rd = wr = ex = 0;
  75.     sigarrived = 0;
  76.  
  77.     while( leave == 0) {
  78.         shift = ( 1 << (fds-1));
  79.         for( i = fds-1; i >= 0; shift >>= 1, --i) {
  80.             /* if data is available for reading mark it as ready */
  81.             if( *rdp & shift && ( _gs_rdy(i) > 0 || (errno == E_UNKSVC))) {
  82.                 rd |= shift;
  83.                 leave++;
  84.             }
  85. #ifndef ONLYRDY
  86.             /* if data is available for writing mark it as ready */
  87.             if( *wrp & shift && ( _gs_wrdy(i) > 0 || (errno == E_UNKSVC))) {
  88.                 wr |= shift;
  89.                 leave++;
  90.             }
  91.             /* if exeption condition is ready mark it as ready */
  92.             if( *exp & shift && ( _gs_erdy(i) > 0 || (errno == E_UNKSVC))) {
  93.                 ex |= shift;
  94.                 leave++;
  95.             }
  96. #endif
  97.         }
  98.         if( leave == 0) {
  99.             /* prepare for waiting .., block signals */
  100.             sigmask(1);
  101.             shift = ( 1 << (fds-1));
  102.             for( i = fds-1; i >= 0; shift >>= 1,  --i) {
  103.                 if( *rdp & shift) {
  104.                     _ss_ssig(i, READY_SIG);
  105.                     signaled |= shift;
  106.                 }
  107. #ifndef ONLYRDY
  108.                 if( *wrp & shift) {
  109.                     _ss_wssig(i, READY_SIG);
  110.                     signaled |= shift;
  111.                 }
  112.                 if( *exp & shift) {
  113.                     _ss_essig(i, READY_SIG);
  114.                     signaled |= shift;
  115.                 }
  116. #endif
  117.             }
  118.             /* wait specified timeout (implicit unblock signal !!) */
  119.             i = tsleep(tout);
  120.             /* if we are interupted, or timed-out get out of here */
  121.             if( sigarrived == 0) {
  122.                 if( i < 0)
  123.                     leave = -1;
  124.                 break;
  125.             }
  126.     }
  127.     }
  128.     /* reset signals .. */
  129.     shift = ( 1 << (fds-1));
  130.     for( i = fds-1; i >= 0; shift >>= 1,  --i)
  131.         if( signaled & shift)
  132.             _ss_rel(i);
  133.     /* get results.. */
  134.     *rdp = rd;
  135.     *wrp = wr;
  136.     *exp = ex;
  137.     return leave;
  138. }
  139.