chiark / gitweb /
Import gnupg2_2.1.18-6.debian.tar.bz2
[gnupg2.git] / patches / gpg-agent-idling / 0003-agent-Avoid-tight-timer-tick-when-possible.patch
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.
4
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.
13
14 --
15
16 With this change, an idle gpg-agent that has no scdaemon running only
17 wakes up once a minute (to check_own_socket).
18
19 Thanks to Ian Jackson and NIIBE Yutaka who helped me improve some of
20 the blocking and corner cases.
21
22 Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
23 ---
24  agent/call-scd.c  |  4 +++-
25  agent/gpg-agent.c | 31 ++++++++++++++++++++++++++++---
26  2 files changed, 31 insertions(+), 4 deletions(-)
27
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)
33  
34    primary_scd_ctx = ctx;
35    primary_scd_ctx_reusable = 0;
36 -
37 +  /* notify the main loop that something has changed */
38 +  interrupt_main_thread_loop ();
39 +  
40   leave:
41    xfree (abs_homedir);
42    if (err)
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)
48  }
49  
50  
51 +static int
52 +need_tick (void)
53 +{
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. */
57 +  return 1;
58 +#else
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))
62 +    return 1;
63 +  /* if scdaemon is running, we need to check that it's alive */
64 +  if (agent_scd_check_running ())
65 +    return 1;
66 +  /* otherwise, nothing fine-grained to do. */
67 +  return 0;
68 +#endif /*HAVE_W32_SYSTEM*/
69 +}
70 +
71  
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)
75  
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.  */
80  static void
81  handle_signal (int signo)
82  {
83 @@ -2618,7 +2638,8 @@ do_start_connection_thread (ctrl_t ctrl)
84  
85    agent_deinit_default_ctrl (ctrl);
86    xfree (ctrl);
87 -  active_connections--;
88 +  if (--active_connections == 0)
89 +    interrupt_main_thread_loop();
90    return NULL;
91  }
92  
93 @@ -2698,7 +2719,8 @@ start_connection_thread_ssh (void *arg)
94  
95    agent_deinit_default_ctrl (ctrl);
96    xfree (ctrl);
97 -  active_connections--;
98 +  if (--active_connections == 0)
99 +    interrupt_main_thread_loop();
100    return NULL;
101  }
102  
103 @@ -2883,6 +2905,9 @@ handle_connections (gnupg_fd_t listen_fd,
104           thus a simple assignment is fine to copy the entire set.  */
105        read_fdset = fdset;
106  
107 +      /* avoid a fine-grained timer if we don't need one: */
108 +      timertbl[0].interval.tv_sec = need_tick () ? TIMERTICK_INTERVAL : 0;
109 +
110        /* loop through all timers, fire any registered functions, and
111           plan next timer to trigger */
112        npth_clock_gettime (&curtime);