static void
handle_tick (void)
{
- static time_t last_minute;
-
- if (!last_minute)
- last_minute = time (NULL);
-
/* Check whether the scdaemon has died and cleanup in this case. */
agent_scd_check_aliveness ();
}
}
#endif /*HAVE_W32_SYSTEM*/
-
- /* Code to be run from time to time. */
-#if CHECK_OWN_SOCKET_INTERVAL > 0
- if (last_minute + CHECK_OWN_SOCKET_INTERVAL <= time (NULL))
- {
- check_own_socket ();
- last_minute = time (NULL);
- }
-#endif
-
}
}
+/* helper function for readability: test whether a given struct
+ timespec is set to all-zeros */
+static inline int
+tv_is_set (struct timespec tv)
+{
+ return tv.tv_sec || tv.tv_nsec;
+}
+
+
/* Connection handler loop. Wait for connection requests and spawn a
thread after accepting a connection. */
static void
gnupg_fd_t fd;
int nfd;
int saved_errno;
+ int idx;
struct timespec abstime;
struct timespec curtime;
struct timespec timeout;
+ struct timespec *select_timeout;
#ifdef HAVE_W32_SYSTEM
HANDLE events[2];
unsigned int events_set;
{ "browser", start_connection_thread_browser },
{ "ssh", start_connection_thread_ssh }
};
+ struct {
+ struct timespec interval;
+ void (*func) (void);
+ struct timespec next;
+ } timertbl[] = {
+ { { TIMERTICK_INTERVAL, 0 }, handle_tick },
+ { { CHECK_OWN_SOCKET_INTERVAL, 0 }, check_own_socket }
+ };
ret = npth_attr_init(&tattr);
listentbl[2].l_fd = listen_fd_browser;
listentbl[3].l_fd = listen_fd_ssh;
- npth_clock_gettime (&abstime);
- abstime.tv_sec += TIMERTICK_INTERVAL;
-
for (;;)
{
/* Shutdown test. */
thus a simple assignment is fine to copy the entire set. */
read_fdset = fdset;
+ /* loop through all timers, fire any registered functions, and
+ plan next timer to trigger */
npth_clock_gettime (&curtime);
- if (!(npth_timercmp (&curtime, &abstime, <)))
- {
- /* Timeout. */
- handle_tick ();
- npth_clock_gettime (&abstime);
- abstime.tv_sec += TIMERTICK_INTERVAL;
- }
- npth_timersub (&abstime, &curtime, &timeout);
+ abstime.tv_sec = abstime.tv_nsec = 0;
+ for (idx=0; idx < DIM(timertbl); idx++)
+ {
+ /* schedule any unscheduled timers */
+ if ((!tv_is_set (timertbl[idx].next)) && tv_is_set (timertbl[idx].interval))
+ npth_timeradd (&timertbl[idx].interval, &curtime, &timertbl[idx].next);
+ /* if a timer is due, fire it ... */
+ if (tv_is_set (timertbl[idx].next))
+ {
+ if (!(npth_timercmp (&curtime, &timertbl[idx].next, <)))
+ {
+ timertbl[idx].func ();
+ npth_clock_gettime (&curtime);
+ /* ...and reschedule it, if desired: */
+ if (tv_is_set (timertbl[idx].interval))
+ npth_timeradd (&timertbl[idx].interval, &curtime, &timertbl[idx].next);
+ else
+ timertbl[idx].next.tv_sec = timertbl[idx].next.tv_nsec = 0;
+ }
+ }
+ /* accumulate next timer to come due in abstime: */
+ if (tv_is_set (timertbl[idx].next) &&
+ ((!tv_is_set (abstime)) ||
+ (npth_timercmp (&abstime, &timertbl[idx].next, >))))
+ abstime = timertbl[idx].next;
+ }
+ /* choose a timeout for the select loop: */
+ if (tv_is_set (abstime))
+ {
+ npth_timersub (&abstime, &curtime, &timeout);
+ select_timeout = &timeout;
+ }
+ else
+ select_timeout = NULL;
+
#ifndef HAVE_W32_SYSTEM
- ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout,
+ ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, select_timeout,
npth_sigev_sigmask ());
saved_errno = errno;
handle_signal (signo);
}
#else
- ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout,
+ ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, select_timeout,
events, &events_set);
saved_errno = errno;
if (!shutdown_pending)
{
- int idx;
ctrl_t ctrl;
npth_t thread;