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. | |||||