Changeset View
Changeset View
Standalone View
Standalone View
b/dirmngr/dirmngr.c
Context not available. | |||||
/* Counter for the active connections. */ | /* Counter for the active connections. */ | ||||
static int active_connections; | static int active_connections; | ||||
/* The timer tick used for housekeeping stuff. For Windows we use a | |||||
longer period as the SetWaitableTimer seems to signal earlier than | |||||
the 2 seconds. All values are in seconds. */ | |||||
#if defined(HAVE_W32CE_SYSTEM) | |||||
# define TIMERTICK_INTERVAL (60) | |||||
#elif defined(HAVE_W32_SYSTEM) | |||||
# define TIMERTICK_INTERVAL (4) | |||||
#else | |||||
# define TIMERTICK_INTERVAL (2) | |||||
#endif | |||||
#define HOUSEKEEPING_INTERVAL (600) | |||||
/* This union is used to avoid compiler warnings in case a pointer is | /* This union is used to avoid compiler warnings in case a pointer is | ||||
64 bit and an int 32 bit. We store an integer in a pointer and get | 64 bit and an int 32 bit. We store an integer in a pointer and get | ||||
it back later (npth_getspecific et al.). */ | it back later (npth_getspecific et al.). */ | ||||
Context not available. | |||||
#endif /*!HAVE_W32_SYSTEM*/ | #endif /*!HAVE_W32_SYSTEM*/ | ||||
/* Thread to do the housekeeping. */ | |||||
static void * | |||||
housekeeping_thread (void *arg) | |||||
{ | |||||
static int sentinel; | |||||
(void)arg; | |||||
if (sentinel) | |||||
{ | |||||
log_info ("housekeeping is already going on\n"); | |||||
return NULL; | |||||
} | |||||
sentinel++; | |||||
if (opt.verbose > 1) | |||||
log_info ("starting housekeeping\n"); | |||||
if (opt.verbose > 1) | |||||
log_info ("ready with housekeeping\n"); | |||||
sentinel--; | |||||
return NULL; | |||||
} | |||||
#if GPGRT_GCC_HAVE_PUSH_PRAGMA | |||||
# pragma GCC push_options | |||||
# pragma GCC optimize ("no-strict-overflow") | |||||
#endif | |||||
static int | |||||
time_for_housekeeping_p (time_t curtime) | |||||
{ | |||||
static time_t last_housekeeping; | |||||
if (!last_housekeeping) | |||||
last_housekeeping = curtime; | |||||
if (last_housekeeping + HOUSEKEEPING_INTERVAL <= curtime | |||||
|| last_housekeeping > curtime /*(be prepared for y2038)*/) | |||||
{ | |||||
last_housekeeping = curtime; | |||||
return 1; | |||||
} | |||||
return 0; | |||||
} | |||||
#if GPGRT_GCC_HAVE_PUSH_PRAGMA | |||||
# pragma GCC pop_options | |||||
#endif | |||||
/* This is the worker for the ticker. It is called every few seconds | |||||
and may only do fast operations. */ | |||||
static void | |||||
handle_tick (void) | |||||
{ | |||||
if (time_for_housekeeping_p (gnupg_get_time ())) | |||||
{ | |||||
npth_t thread; | |||||
npth_attr_t tattr; | |||||
int err; | |||||
err = npth_attr_init (&tattr); | |||||
if (err) | |||||
log_error ("error preparing housekeeping thread: %s\n", strerror (err)); | |||||
else | |||||
{ | |||||
npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED); | |||||
err = npth_create (&thread, &tattr, housekeeping_thread, NULL); | |||||
if (err) | |||||
log_error ("error spawning housekeeping thread: %s\n", | |||||
strerror (err)); | |||||
npth_attr_destroy (&tattr); | |||||
} | |||||
} | |||||
} | |||||
/* Check the nonce on a new connection. This is a NOP unless we are | /* Check the nonce on a new connection. This is a NOP unless we are | ||||
using our Unix domain socket emulation under Windows. */ | using our Unix domain socket emulation under Windows. */ | ||||
static int | static int | ||||
Context not available. | |||||
gnupg_fd_t fd; | gnupg_fd_t fd; | ||||
int nfd, ret; | int nfd, ret; | ||||
fd_set fdset, read_fdset; | fd_set fdset, read_fdset; | ||||
struct timespec abstime; | |||||
struct timespec curtime; | |||||
struct timespec timeout; | |||||
int saved_errno; | int saved_errno; | ||||
#ifdef HAVE_INOTIFY_INIT | #ifdef HAVE_INOTIFY_INIT | ||||
int my_inotify_fd; | int my_inotify_fd; | ||||
Context not available. | |||||
#endif /*HAVE_INOTIFY_INIT*/ | #endif /*HAVE_INOTIFY_INIT*/ | ||||
/* Setup the fdset. It has only one member. This is because we use | /* Setup the fdset. */ | ||||
pth_select instead of pth_accept to properly sync timeouts with | |||||
to full second. */ | |||||
FD_ZERO (&fdset); | FD_ZERO (&fdset); | ||||
FD_SET (FD2INT (listen_fd), &fdset); | FD_SET (FD2INT (listen_fd), &fdset); | ||||
nfd = FD2INT (listen_fd); | nfd = FD2INT (listen_fd); | ||||
Context not available. | |||||
} | } | ||||
#endif /*HAVE_INOTIFY_INIT*/ | #endif /*HAVE_INOTIFY_INIT*/ | ||||
npth_clock_gettime (&abstime); | |||||
abstime.tv_sec += TIMERTICK_INTERVAL; | |||||
/* Main loop. */ | /* Main loop. */ | ||||
for (;;) | for (;;) | ||||
{ | { | ||||
Context not available. | |||||
break; /* ready */ | break; /* ready */ | ||||
/* Do not accept new connections but keep on running the | /* Do not accept new connections but keep on running the | ||||
loop to cope with the timer events. */ | select loop to wait for signals (e.g. SIGCHLD). */ | ||||
FD_ZERO (&fdset); | FD_ZERO (&fdset); | ||||
} | } | ||||
/* Take a copy of the fdset. */ | /* Take a copy of the fdset. */ | ||||
read_fdset = fdset; | read_fdset = fdset; | ||||
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); | |||||
#ifndef HAVE_W32_SYSTEM | #ifndef HAVE_W32_SYSTEM | ||||
ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask()); | ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, NULL, npth_sigev_sigmask()); | ||||
saved_errno = errno; | saved_errno = errno; | ||||
while (npth_sigev_get_pending(&signo)) | while (npth_sigev_get_pending(&signo)) | ||||
handle_signal (signo); | handle_signal (signo); | ||||
#else | #else | ||||
ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, NULL, NULL); | ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, NULL, NULL, NULL); | ||||
saved_errno = errno; | saved_errno = errno; | ||||
#endif | #endif | ||||
Context not available. | |||||
if (ret <= 0) | if (ret <= 0) | ||||
{ | { | ||||
/* Interrupt or timeout. Will be handled when calculating the | /* Interrupt. Will be handled at the top of the next loop. */ | ||||
next timeout. */ | |||||
continue; | continue; | ||||
} | } | ||||
Context not available. |