X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=gnupg2.git;a=blobdiff_plain;f=agent%2Fgpg-agent.c;h=0e53549479f56044d4b26a9de2482193a41ceddd;hp=82c8ae0621a443e604cb785711aaa16925f9e6a4;hb=refs%2Fheads%2F841143-extra-debug-messages;hpb=c224dda498a321a715e9f1a5e61c371d289f8657 diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 82c8ae0..0e53549 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -382,6 +382,9 @@ static char *current_logfile; watched. */ static pid_t parent_pid = (pid_t)(-1); +/* Record the pid of the main thread, for easier signalling */ +static pid_t main_thread_pid = (pid_t)(-1); + /* Number of active connections. */ static int active_connections; @@ -2020,7 +2023,7 @@ get_agent_scd_notify_event (void) GetCurrentProcess(), &h2, EVENT_MODIFY_STATE|SYNCHRONIZE, TRUE, 0)) { - log_error ("setting syncronize for scd notify event failed: %s\n", + log_error ("setting synchronize for scd notify event failed: %s\n", w32_strerror (-1) ); CloseHandle (h); } @@ -2264,6 +2267,26 @@ create_directories (void) } +static int +need_tick (void) +{ +#ifdef HAVE_W32_SYSTEM + /* We do not know how to interrupt the select loop on Windows, so we + always need a short tick there. */ + return 1; +#else + /* if we were invoked like "gpg-agent cmd arg1 arg2" then we need to + watch our parent. */ + if (parent_pid != (pid_t)(-1)) + return 1; + /* if scdaemon is running, we need to check that it's alive */ + if (agent_scd_check_running ()) + return 1; + /* otherwise, nothing fine-grained to do. */ + return 0; +#endif /*HAVE_W32_SYSTEM*/ +} + /* This is the worker for the ticker. It is called every few seconds and may only do fast operations. */ @@ -2322,7 +2345,7 @@ agent_sigusr2_action (void) #ifndef HAVE_W32_SYSTEM /* The signal handler for this program. It is expected to be run in - its own trhead and not in the context of a signal handler. */ + its own thread and not in the context of a signal handler. */ static void handle_signal (int signo) { @@ -2346,6 +2369,10 @@ handle_signal (int signo) agent_sigusr2_action (); break; + /* nothing to do here, just take an extra cycle on the select loop */ + case SIGCONT: + break; + case SIGTERM: if (!shutdown_pending) log_info ("SIGTERM received - shutting down ...\n"); @@ -2684,6 +2711,13 @@ start_connection_thread_ssh (void *arg) } +void interrupt_main_thread_loop (void) +{ +#ifndef HAVE_W32_SYSTEM + kill (main_thread_pid, SIGCONT); +#endif +} + /* helper function for readability: test whether a given struct timespec is set to all-zeros */ static inline int @@ -2752,8 +2786,10 @@ handle_connections (gnupg_fd_t listen_fd, npth_sigev_add (SIGUSR1); npth_sigev_add (SIGUSR2); npth_sigev_add (SIGINT); + npth_sigev_add (SIGCONT); npth_sigev_add (SIGTERM); npth_sigev_fini (); + main_thread_pid = getpid (); #else # ifdef HAVE_W32CE_SYSTEM /* Use a dummy event. */ @@ -2765,6 +2801,7 @@ handle_connections (gnupg_fd_t listen_fd, # endif #endif + if (disable_check_own_socket) my_inotify_fd = -1; else if ((err = gnupg_inotify_watch_socket (&my_inotify_fd, socket_name))) @@ -2855,6 +2892,11 @@ handle_connections (gnupg_fd_t listen_fd, thus a simple assignment is fine to copy the entire set. */ read_fdset = fdset; + /* avoid a fine-grained timer if we don't need one: */ + timertbl[0].interval.tv_sec = need_tick () ? TIMERTICK_INTERVAL : 0; + /* avoid waking up to check sockets if we can count on inotify */ + timertbl[1].interval.tv_sec = (my_inotify_fd == -1) ? CHECK_OWN_SOCKET_INTERVAL : 0; + /* loop through all timers, fire any registered functions, and plan next timer to trigger */ npth_clock_gettime (&curtime);