1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
Date: Tue, 1 Nov 2016 00:45:23 -0400
Subject: agent: Allow threads to interrupt main select loop with SIGCONT.
* agent/gpg-agent.c (interrupt_main_thread_loop): New function on
non-windows platforms, allows other threads to interrupt the main loop
if there's something that the main loop might be interested in.
--
For example, the main loop might be interested in changes in program
state that affect the timers it expects to see.
I don't know how to do this on Windows platforms, but i welcome any
proposed improvements.
Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
---
agent/agent.h | 1 +
agent/gpg-agent.c | 16 ++++++++++++++++
2 files changed, 17 insertions(+)
diff --git a/agent/agent.h b/agent/agent.h
index 56e13ec..d1abf26 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -391,6 +391,7 @@ void *get_agent_scd_notify_event (void);
#endif
void agent_sighup_action (void);
int map_pk_openpgp_to_gcry (int openpgp_algo);
+void interrupt_main_thread_loop (void);
/*-- command.c --*/
gpg_error_t agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid,
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index 309e87c..2882767 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -462,6 +462,9 @@ static int have_homedir_inotify;
* works reliable. */
static int reliable_homedir_inotify;
+/* 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;
@@ -2470,6 +2473,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");
@@ -2808,6 +2815,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
@@ -2877,8 +2891,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. */
|