Changeset View
Changeset View
Standalone View
Standalone View
b/agent/gpg-agent.c
Context not available. | |||||
static void | static void | ||||
handle_tick (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. */ | /* Check whether the scdaemon has died and cleanup in this case. */ | ||||
agent_scd_check_aliveness (); | agent_scd_check_aliveness (); | ||||
Context not available. | |||||
} | } | ||||
} | } | ||||
#endif /*HAVE_W32_SYSTEM*/ | #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 | |||||
} | } | ||||
Context not available. | |||||
} | } | ||||
/* 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 | /* Connection handler loop. Wait for connection requests and spawn a | ||||
thread after accepting a connection. */ | thread after accepting a connection. */ | ||||
static void | static void | ||||
Context not available. | |||||
gnupg_fd_t fd; | gnupg_fd_t fd; | ||||
int nfd; | int nfd; | ||||
int saved_errno; | int saved_errno; | ||||
int idx; | |||||
struct timespec abstime; | struct timespec abstime; | ||||
struct timespec curtime; | struct timespec curtime; | ||||
struct timespec timeout; | struct timespec timeout; | ||||
struct timespec *select_timeout; | |||||
#ifdef HAVE_W32_SYSTEM | #ifdef HAVE_W32_SYSTEM | ||||
HANDLE events[2]; | HANDLE events[2]; | ||||
unsigned int events_set; | unsigned int events_set; | ||||
Context not available. | |||||
{ "browser", start_connection_thread_browser }, | { "browser", start_connection_thread_browser }, | ||||
{ "ssh", start_connection_thread_ssh } | { "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); | ret = npth_attr_init(&tattr); | ||||
Context not available. | |||||
listentbl[2].l_fd = listen_fd_browser; | listentbl[2].l_fd = listen_fd_browser; | ||||
listentbl[3].l_fd = listen_fd_ssh; | listentbl[3].l_fd = listen_fd_ssh; | ||||
npth_clock_gettime (&abstime); | |||||
abstime.tv_sec += TIMERTICK_INTERVAL; | |||||
for (;;) | for (;;) | ||||
{ | { | ||||
/* Shutdown test. */ | /* Shutdown test. */ | ||||
Context not available. | |||||
thus a simple assignment is fine to copy the entire set. */ | thus a simple assignment is fine to copy the entire set. */ | ||||
read_fdset = fdset; | read_fdset = fdset; | ||||
/* loop through all timers, fire any registered functions, and | |||||
plan next timer to trigger */ | |||||
npth_clock_gettime (&curtime); | npth_clock_gettime (&curtime); | ||||
if (!(npth_timercmp (&curtime, &abstime, <))) | abstime.tv_sec = abstime.tv_nsec = 0; | ||||
{ | for (idx=0; idx < DIM(timertbl); idx++) | ||||
/* Timeout. */ | { | ||||
handle_tick (); | /* schedule any unscheduled timers */ | ||||
npth_clock_gettime (&abstime); | if ((!tv_is_set (timertbl[idx].next)) && tv_is_set (timertbl[idx].interval)) | ||||
abstime.tv_sec += TIMERTICK_INTERVAL; | npth_timeradd (&timertbl[idx].interval, &curtime, &timertbl[idx].next); | ||||
} | /* if a timer is due, fire it ... */ | ||||
npth_timersub (&abstime, &curtime, &timeout); | 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 | #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 ()); | npth_sigev_sigmask ()); | ||||
saved_errno = errno; | saved_errno = errno; | ||||
Context not available. | |||||
handle_signal (signo); | handle_signal (signo); | ||||
} | } | ||||
#else | #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); | events, &events_set); | ||||
saved_errno = errno; | saved_errno = errno; | ||||
Context not available. | |||||
if (!shutdown_pending) | if (!shutdown_pending) | ||||
{ | { | ||||
int idx; | |||||
ctrl_t ctrl; | ctrl_t ctrl; | ||||
npth_t thread; | npth_t thread; | ||||
Context not available. |