1 From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
2 Date: Tue, 1 Nov 2016 00:14:10 -0400
3 Subject: agent: Avoid tight timer tick when possible.
5 * agent/gpg-agent.c (need_tick): Evaluate whether the short-phase
6 handle_tick() is needed.
7 (handle_connections): On each cycle of the select loop, adjust whether
8 we should call handle_tick() or not.
9 (start_connection_thread_ssh, do_start_connection_thread): Signal the
10 main loop when the child terminates.
11 * agent/call-scd.c (start_scd): Call interrupt_main_thread_loop() once
12 the scdaemon thread context has started up.
16 With this change, an idle gpg-agent that has no scdaemon running only
17 wakes up once a minute (to check_own_socket).
19 Thanks to Ian Jackson and NIIBE Yutaka who helped me improve some of
20 the blocking and corner cases.
22 Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
24 agent/call-scd.c | 4 +++-
25 agent/gpg-agent.c | 31 ++++++++++++++++++++++++++++---
26 2 files changed, 31 insertions(+), 4 deletions(-)
28 diff --git a/agent/call-scd.c b/agent/call-scd.c
29 index 15a2ba529..0bf603084 100644
30 --- a/agent/call-scd.c
31 +++ b/agent/call-scd.c
32 @@ -407,7 +407,9 @@ start_scd (ctrl_t ctrl)
34 primary_scd_ctx = ctx;
35 primary_scd_ctx_reusable = 0;
37 + /* notify the main loop that something has changed */
38 + interrupt_main_thread_loop ();
43 diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
44 index 73cd560aa..b33de7d39 100644
45 --- a/agent/gpg-agent.c
46 +++ b/agent/gpg-agent.c
47 @@ -2279,6 +2279,26 @@ create_directories (void)
54 +#ifdef HAVE_W32_SYSTEM
55 + /* We do not know how to interrupt the select loop on Windows, so we
56 + always need a short tick there. */
59 + /* if we were invoked like "gpg-agent cmd arg1 arg2" then we need to
60 + watch our parent. */
61 + if (parent_pid != (pid_t)(-1))
63 + /* if scdaemon is running, we need to check that it's alive */
64 + if (agent_scd_check_running ())
66 + /* otherwise, nothing fine-grained to do. */
68 +#endif /*HAVE_W32_SYSTEM*/
72 /* This is the worker for the ticker. It is called every few seconds
73 and may only do fast operations. */
74 @@ -2337,7 +2357,7 @@ agent_sigusr2_action (void)
76 #ifndef HAVE_W32_SYSTEM
77 /* The signal handler for this program. It is expected to be run in
78 - its own trhead and not in the context of a signal handler. */
79 + its own thread and not in the context of a signal handler. */
81 handle_signal (int signo)
83 @@ -2618,7 +2638,8 @@ do_start_connection_thread (ctrl_t ctrl)
85 agent_deinit_default_ctrl (ctrl);
87 - active_connections--;
88 + if (--active_connections == 0)
89 + interrupt_main_thread_loop();
93 @@ -2698,7 +2719,8 @@ start_connection_thread_ssh (void *arg)
95 agent_deinit_default_ctrl (ctrl);
97 - active_connections--;
98 + if (--active_connections == 0)
99 + interrupt_main_thread_loop();
103 @@ -2883,6 +2905,9 @@ handle_connections (gnupg_fd_t listen_fd,
104 thus a simple assignment is fine to copy the entire set. */
107 + /* avoid a fine-grained timer if we don't need one: */
108 + timertbl[0].interval.tv_sec = need_tick () ? TIMERTICK_INTERVAL : 0;
110 /* loop through all timers, fire any registered functions, and
111 plan next timer to trigger */
112 npth_clock_gettime (&curtime);