chiark / gitweb /
6d294d3fa7d690b38e2daaecd62b733febae569b
[gnupg2.git] / patches / gpg-agent-idling / 0002-agent-Allow-threads-to-interrupt-main-select-loop-wi.patch
1 From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
2 Date: Tue, 1 Nov 2016 00:45:23 -0400
3 Subject: agent: Allow threads to interrupt main select loop with SIGCONT.
4
5 * agent/gpg-agent.c (interrupt_main_thread_loop): New function on
6 non-windows platforms, allows other threads to interrupt the main loop
7 if there's something that the main loop might be interested in.
8
9 --
10
11 For example, the main loop might be interested in changes in program
12 state that affect the timers it expects to see.
13
14 I don't know how to do this on Windows platforms, but i welcome any
15 proposed improvements.
16
17 Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
18 ---
19  agent/agent.h     |  1 +
20  agent/gpg-agent.c | 19 ++++++++++++++++++-
21  2 files changed, 19 insertions(+), 1 deletion(-)
22
23 diff --git a/agent/agent.h b/agent/agent.h
24 index 89dc46d05..147d242ec 100644
25 --- a/agent/agent.h
26 +++ b/agent/agent.h
27 @@ -345,6 +345,7 @@ void *get_agent_scd_notify_event (void);
28  #endif
29  void agent_sighup_action (void);
30  int map_pk_openpgp_to_gcry (int openpgp_algo);
31 +void interrupt_main_thread_loop (void);
32  
33  /*-- command.c --*/
34  gpg_error_t agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid,
35 diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
36 index 82c8ae062..04a775c9b 100644
37 --- a/agent/gpg-agent.c
38 +++ b/agent/gpg-agent.c
39 @@ -382,6 +382,9 @@ static char *current_logfile;
40     watched. */
41  static pid_t parent_pid = (pid_t)(-1);
42  
43 +/* Record the pid of the main thread, for easier signalling */
44 +static pid_t main_thread_pid = (pid_t)(-1);
45 +
46  /* Number of active connections.  */
47  static int active_connections;
48  
49 @@ -2020,7 +2023,7 @@ get_agent_scd_notify_event (void)
50                                   GetCurrentProcess(), &h2,
51                                   EVENT_MODIFY_STATE|SYNCHRONIZE, TRUE, 0))
52          {
53 -          log_error ("setting syncronize for scd notify event failed: %s\n",
54 +          log_error ("setting synchronize for scd notify event failed: %s\n",
55                       w32_strerror (-1) );
56            CloseHandle (h);
57          }
58 @@ -2346,6 +2349,10 @@ handle_signal (int signo)
59        agent_sigusr2_action ();
60        break;
61  
62 +      /* nothing to do here, just take an extra cycle on the select loop */
63 +    case SIGCONT:
64 +      break;
65 +
66      case SIGTERM:
67        if (!shutdown_pending)
68          log_info ("SIGTERM received - shutting down ...\n");
69 @@ -2684,6 +2691,13 @@ start_connection_thread_ssh (void *arg)
70  }
71  
72  
73 +void interrupt_main_thread_loop (void)
74 +{
75 +#ifndef HAVE_W32_SYSTEM
76 +  kill (main_thread_pid, SIGCONT);
77 +#endif
78 +}
79 +
80  /* helper function for readability: test whether a given struct
81     timespec is set to all-zeros */
82  static inline int
83 @@ -2752,8 +2766,10 @@ handle_connections (gnupg_fd_t listen_fd,
84    npth_sigev_add (SIGUSR1);
85    npth_sigev_add (SIGUSR2);
86    npth_sigev_add (SIGINT);
87 +  npth_sigev_add (SIGCONT);
88    npth_sigev_add (SIGTERM);
89    npth_sigev_fini ();
90 +  main_thread_pid = getpid ();
91  #else
92  # ifdef HAVE_W32CE_SYSTEM
93    /* Use a dummy event. */
94 @@ -2765,6 +2781,7 @@ handle_connections (gnupg_fd_t listen_fd,
95  # endif
96  #endif
97  
98 +
99    if (disable_check_own_socket)
100      my_inotify_fd = -1;
101    else if ((err = gnupg_inotify_watch_socket (&my_inotify_fd, socket_name)))