This is timer.c in view mode; [Download] [Up]
/* * Machinery to run routines off timers. */ #include "common.h" #ifdef TIMERS #ifndef lint static char rcsid[] = "@(#) $Header: timer.c,v 1.2 90/12/27 22:16:27 sob Exp $ (NNTP with TIMERS)"; #endif #else #ifndef lint static char rcsid[] = "@(#) $Header: timer.c,v 1.2 90/12/27 22:16:27 sob Exp $ (NNTP without TIMERS)"; #endif #endif #ifdef TIMERS #include <sys/time.h> #include "timer.h" #ifndef USG #ifndef FD_SETSIZE /* Forward compatability */ #define FD_SET(n, p) ((p)->fds_bits[0] |= (1<<(n))) #define FD_CLR(n, p) ((p)->fds_bits[0] &= ~(1<<(n))) #define FD_ISSET(n, p) ((p)->fds_bits[0] & (1<<(n))) #define FD_ZERO(p) ((p)->fds_bits[0] = 0) #endif #endif /* non-portable */ #define BUFFERED_DATA(f) ((f)->_cnt > 0) static long lastsecs; /* * Should be called before first call to timer_sleep() */ void timer_init(timers, ntimer) register struct timer *timers; register int ntimer; { register int i; register struct timer *tp; #ifdef SYSLOG if (ntimer <= 0) syslog(LOG_ERR, "timer_init(): configuration error, %d timers\n", ntimer); #endif /* Reset all timers */ for (i = ntimer, tp = timers; i > 0; --i, ++tp) tp->left = tp->seconds; /* Start clock */ lastsecs = time((long *)0); } /* * Sleep until input or next timer needs to be run and then run any * expired timers. Returns true if input is available to be read. */ int timer_sleep(timers, ntimer) register struct timer *timers; register int ntimer; { register int i, n; register struct timer *tp; register long secs; #ifdef USG long timeout; long readfds; #else register struct timeval *timeoutp; struct timeval timeout; fd_set readfds; #endif /* No need to do the select if there are characters in the buffer */ if (BUFFERED_DATA(stdin)) return(1); /* Length of next timeout is minimum of all "timers" */ #ifdef USG timeout = -1; for (i = ntimer, tp = timers; i > 0; --i, ++tp) if (tp->left >= 0 && (tp->left < timeout || timeout < 0)) timeout = tp->left; /* If active timeouts (this can easily happen), block until input */ if (timeout < 0) timeout = 0; #ifdef EXCELAN readfds = 1<<(fileno(stdin)); timeout = timeout * 1000; /* timeout needs to be in milliseconds */ #endif /* EXCELAN */ #else timeout.tv_sec = -1; timeout.tv_usec = 0; for (i = ntimer, tp = timers; i > 0; --i, ++tp) if (tp->left >= 0 && (tp->left < timeout.tv_sec || timeout.tv_sec < 0)) timeout.tv_sec = tp->left; /* If active timeouts (this can easily happen), block until input */ if (timeout.tv_sec < 0) timeoutp = 0; else timeoutp = &timeout; /* Do select */ FD_ZERO(&readfds); FD_SET(fileno(stdin), &readfds); #endif /* !USG */ errno = 0; #ifdef EXCELAN n = select(fileno(stdin) + 1, &readfds, (long*)0, timeout); #else n = select(fileno(stdin) + 1, &readfds, (fd_set*)0, (fd_set*)0, timeoutp); #endif /* "Interrupted system call" isn't a real error */ if (n < 0 && errno != EINTR) { #ifdef SYSLOG syslog(LOG_ERR, "%s read select: %m", hostname); #endif exit(1); } /* Calculate off seconds since last time */ secs = time((long *)0) - lastsecs; if (secs < 0) secs = 0; /* Subtract time from "timers" that have time remaining */ for (i = ntimer, tp = timers; i > 0; --i, ++tp) if (tp->left > 0 && (tp->left -= secs) < 0) tp->left = 0; /* Update lastsecs */ lastsecs += secs; /* If we have input, reset clock on guys that like it that way */ if (n > 0) for (i = ntimer, tp = timers; i > 0; --i, ++tp) if (tp->resetoninput) tp->left = tp->seconds; /* Process "timers" that have timed out */ for (i = ntimer, tp = timers; i > 0; --i, ++tp) { if (tp->left == 0) { (tp->subr)(); /* resetoninput guys only get "reset on input" */ if (tp->resetoninput) tp->left = -1; else tp->left = tp->seconds; } } /* Indicate no input */ if (n <= 0) return(0); return(1); } #endif
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.