home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NNTP-1.000 / NNTP-1 / nntp.1.5.11t / server / timer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-17  |  3.8 KB  |  175 lines

  1. /*
  2.  * Machinery to run routines off timers.
  3.  */
  4. #include "common.h"
  5.  
  6. #ifdef TIMERS
  7. #ifndef lint
  8. static char rcsid[] =
  9.     "@(#) $Header: timer.c,v 1.2 90/12/27 22:16:27 sob Exp $ (NNTP with TIMERS)";
  10. #endif
  11. #else
  12. #ifndef lint
  13. static char rcsid[] =
  14.     "@(#) $Header: timer.c,v 1.2 90/12/27 22:16:27 sob Exp $ (NNTP without TIMERS)";
  15. #endif
  16. #endif
  17.  
  18. #ifdef TIMERS
  19. #include <sys/times.h>
  20. #include "timer.h"
  21. #ifndef USG
  22. #ifndef FD_SETSIZE
  23. /* Forward compatability */
  24. #define FD_SET(n, p)    ((p)->fds_bits[0] |= (1<<(n)))
  25. #define FD_CLR(n, p)    ((p)->fds_bits[0] &= ~(1<<(n)))
  26. #define FD_ISSET(n, p)  ((p)->fds_bits[0] & (1<<(n)))
  27. #define FD_ZERO(p)      ((p)->fds_bits[0] = 0)
  28. #endif
  29. #endif
  30. /* non-portable */
  31. #if 0
  32. #define BUFFERED_DATA(f) ((f)->_cnt > 0)
  33. #endif
  34.  
  35. static long lastsecs;
  36.  
  37. /*
  38.  * Should be called before first call to timer_sleep()
  39.  */
  40. void
  41. timer_init(timers, ntimer)
  42.     register struct timer *timers;
  43.     register int ntimer;
  44. {
  45.     register int i;
  46.     register struct timer *tp;
  47.  
  48. #ifdef SYSLOG
  49.     if (ntimer <= 0)
  50.         syslog(LOG_ERR,
  51.             "timer_init(): configuration error, %d timers\n", ntimer);
  52. #endif
  53.  
  54.     /* Reset all timers */
  55.     for (i = ntimer, tp = timers; i > 0; --i, ++tp)
  56.         tp->left = tp->seconds;
  57.  
  58.     /* Start clock */
  59.     lastsecs = time((long *)0);
  60. }
  61.  
  62. /*
  63.  * Sleep until input or next timer needs to be run and then run any
  64.  * expired timers. Returns true if input is available to be read.
  65.  */
  66. int
  67. timer_sleep(timers, ntimer)
  68.     register struct timer *timers;
  69.     register int ntimer;
  70. {
  71.     register int i, n;
  72.     register struct timer *tp;
  73.     register long secs;
  74. #ifdef USG
  75.     long timeout;
  76.     long readfds;
  77. #else
  78.     register struct timeval *timeoutp;
  79.     struct timeval timeout;
  80.     fd_set readfds;
  81. #endif
  82.  
  83.     /* No need to do the select if there are characters in the buffer */
  84. #if 0
  85.     if (BUFFERED_DATA(stdin))
  86.         return(1);
  87. #endif
  88.  
  89.     /* Length of next timeout is minimum of all "timers" */
  90. #ifdef USG
  91.     timeout = -1;
  92.     for (i = ntimer, tp = timers; i > 0; --i, ++tp)
  93.         if (tp->left >= 0 &&
  94.             (tp->left < timeout || timeout < 0))
  95.             timeout = tp->left;
  96.  
  97.     /* If active timeouts (this can easily happen), block until input */
  98.     if (timeout < 0)
  99.         timeout = 0;
  100. #ifdef EXCELAN
  101.     readfds = 1<<(fileno(stdin));
  102.     timeout = timeout * 1000;     /* timeout needs to be in milliseconds */
  103. #endif /* EXCELAN */
  104. #else
  105.     timeout.tv_sec = -1;
  106.     timeout.tv_usec = 0;
  107.     for (i = ntimer, tp = timers; i > 0; --i, ++tp)
  108.         if (tp->left >= 0 &&
  109.             (tp->left < timeout.tv_sec || timeout.tv_sec < 0))
  110.             timeout.tv_sec = tp->left;
  111.  
  112.     /* If active timeouts (this can easily happen), block until input */
  113.     if (timeout.tv_sec < 0)
  114.         timeoutp = 0;
  115.     else
  116.         timeoutp = &timeout;
  117.  
  118.     /* Do select */
  119.     FD_ZERO(&readfds);
  120.     FD_SET(fileno(stdin), &readfds);
  121. #endif /* !USG */
  122.     errno = 0;
  123. #if 1 /* Was EXECLAN */
  124.     n = select(fileno(stdin) + 1, &readfds, (long*)0, timeout);
  125. #else
  126.     n = select(fileno(stdin) + 1,
  127.         &readfds, (fd_set*)0, (fd_set*)0, timeoutp);
  128. #endif
  129.     /* "Interrupted system call" isn't a real error */
  130.     if (n < 0 && errno != EINTR) {
  131. #ifdef SYSLOG
  132.         syslog(LOG_ERR, "%s read select: %m", hostname);
  133. #endif
  134.         exit(1);
  135.     }
  136.  
  137.     /* Calculate off seconds since last time */
  138.     secs = time((long *)0) - lastsecs;
  139.     if (secs < 0)
  140.         secs = 0;
  141.  
  142.     /* Subtract time from "timers" that have time remaining */
  143.     for (i = ntimer, tp = timers; i > 0; --i, ++tp)
  144.         if (tp->left > 0 && (tp->left -= secs) < 0)
  145.             tp->left = 0;
  146.  
  147.     /* Update lastsecs */
  148.     lastsecs += secs;
  149.  
  150.     /* If we have input, reset clock on guys that like it that way */
  151.     if (n > 0)
  152.         for (i = ntimer, tp = timers; i > 0; --i, ++tp)
  153.             if (tp->resetoninput)
  154.                 tp->left = tp->seconds;
  155.  
  156.     /* Process "timers" that have timed out */
  157.     for (i = ntimer, tp = timers; i > 0; --i, ++tp) {
  158.         if (tp->left == 0) {
  159.             (tp->subr)();
  160.             /* resetoninput guys only get "reset on input" */
  161.             if (tp->resetoninput)
  162.                 tp->left = -1;
  163.             else
  164.                 tp->left = tp->seconds;
  165.         }
  166.     }
  167.  
  168.     /* Indicate no input */
  169.     if (n <= 0)
  170.         return(0);
  171.     return(1);
  172.     
  173. }
  174. #endif
  175.