gdb: give names to async event/signal handlers
[binutils-gdb.git] / gdb / async-event.c
1 /* Async events for the GDB event loop.
2 Copyright (C) 1999-2020 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19 #include "defs.h"
20 #include "async-event.h"
21
22 #include "ser-event.h"
23 #include "top.h"
24
25 /* PROC is a function to be invoked when the READY flag is set. This
26 happens when there has been a signal and the corresponding signal
27 handler has 'triggered' this async_signal_handler for execution.
28 The actual work to be done in response to a signal will be carried
29 out by PROC at a later time, within process_event. This provides a
30 deferred execution of signal handlers.
31
32 Async_init_signals takes care of setting up such an
33 async_signal_handler for each interesting signal. */
34
35 struct async_signal_handler
36 {
37 /* If ready, call this handler from the main event loop, using
38 invoke_async_handler. */
39 int ready;
40
41 /* Pointer to next handler. */
42 struct async_signal_handler *next_handler;
43
44 /* Function to call to do the work. */
45 sig_handler_func *proc;
46
47 /* Argument to PROC. */
48 gdb_client_data client_data;
49
50 /* User-friendly name of this handler. */
51 const char *name;
52 };
53
54 /* PROC is a function to be invoked when the READY flag is set. This
55 happens when the event has been marked with
56 MARK_ASYNC_EVENT_HANDLER. The actual work to be done in response
57 to an event will be carried out by PROC at a later time, within
58 process_event. This provides a deferred execution of event
59 handlers. */
60 struct async_event_handler
61 {
62 /* If ready, call this handler from the main event loop, using
63 invoke_event_handler. */
64 int ready;
65
66 /* Pointer to next handler. */
67 struct async_event_handler *next_handler;
68
69 /* Function to call to do the work. */
70 async_event_handler_func *proc;
71
72 /* Argument to PROC. */
73 gdb_client_data client_data;
74
75 /* User-friendly name of this handler. */
76 const char *name;
77 };
78
79 /* All the async_signal_handlers gdb is interested in are kept onto
80 this list. */
81 static struct
82 {
83 /* Pointer to first in handler list. */
84 async_signal_handler *first_handler;
85
86 /* Pointer to last in handler list. */
87 async_signal_handler *last_handler;
88 }
89 sighandler_list;
90
91 /* All the async_event_handlers gdb is interested in are kept onto
92 this list. */
93 static struct
94 {
95 /* Pointer to first in handler list. */
96 async_event_handler *first_handler;
97
98 /* Pointer to last in handler list. */
99 async_event_handler *last_handler;
100 }
101 async_event_handler_list;
102
103
104 /* This event is signalled whenever an asynchronous handler needs to
105 defer an action to the event loop. */
106 static struct serial_event *async_signal_handlers_serial_event;
107
108 /* Callback registered with ASYNC_SIGNAL_HANDLERS_SERIAL_EVENT. */
109
110 static void
111 async_signals_handler (int error, gdb_client_data client_data)
112 {
113 /* Do nothing. Handlers are run by invoke_async_signal_handlers
114 from instead. */
115 }
116
117 void
118 initialize_async_signal_handlers (void)
119 {
120 async_signal_handlers_serial_event = make_serial_event ();
121
122 add_file_handler (serial_event_fd (async_signal_handlers_serial_event),
123 async_signals_handler, NULL, "async-signals");
124 }
125
126 \f
127
128 /* Create an asynchronous handler, allocating memory for it.
129 Return a pointer to the newly created handler.
130 This pointer will be used to invoke the handler by
131 invoke_async_signal_handler.
132 PROC is the function to call with CLIENT_DATA argument
133 whenever the handler is invoked. */
134 async_signal_handler *
135 create_async_signal_handler (sig_handler_func * proc,
136 gdb_client_data client_data,
137 const char *name)
138 {
139 async_signal_handler *async_handler_ptr;
140
141 async_handler_ptr = XNEW (async_signal_handler);
142 async_handler_ptr->ready = 0;
143 async_handler_ptr->next_handler = NULL;
144 async_handler_ptr->proc = proc;
145 async_handler_ptr->client_data = client_data;
146 async_handler_ptr->name = name;
147 if (sighandler_list.first_handler == NULL)
148 sighandler_list.first_handler = async_handler_ptr;
149 else
150 sighandler_list.last_handler->next_handler = async_handler_ptr;
151 sighandler_list.last_handler = async_handler_ptr;
152 return async_handler_ptr;
153 }
154
155 /* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
156 will be used when the handlers are invoked, after we have waited
157 for some event. The caller of this function is the interrupt
158 handler associated with a signal. */
159 void
160 mark_async_signal_handler (async_signal_handler * async_handler_ptr)
161 {
162 async_handler_ptr->ready = 1;
163 serial_event_set (async_signal_handlers_serial_event);
164 }
165
166 /* See event-loop.h. */
167
168 void
169 clear_async_signal_handler (async_signal_handler *async_handler_ptr)
170 {
171 async_handler_ptr->ready = 0;
172 }
173
174 /* See event-loop.h. */
175
176 int
177 async_signal_handler_is_marked (async_signal_handler *async_handler_ptr)
178 {
179 return async_handler_ptr->ready;
180 }
181
182 /* Call all the handlers that are ready. Returns true if any was
183 indeed ready. */
184
185 int
186 invoke_async_signal_handlers (void)
187 {
188 async_signal_handler *async_handler_ptr;
189 int any_ready = 0;
190
191 /* We're going to handle all pending signals, so no need to wake up
192 the event loop again the next time around. Note this must be
193 cleared _before_ calling the callbacks, to avoid races. */
194 serial_event_clear (async_signal_handlers_serial_event);
195
196 /* Invoke all ready handlers. */
197
198 while (1)
199 {
200 for (async_handler_ptr = sighandler_list.first_handler;
201 async_handler_ptr != NULL;
202 async_handler_ptr = async_handler_ptr->next_handler)
203 {
204 if (async_handler_ptr->ready)
205 break;
206 }
207 if (async_handler_ptr == NULL)
208 break;
209 any_ready = 1;
210 async_handler_ptr->ready = 0;
211 /* Async signal handlers have no connection to whichever was the
212 current UI, and thus always run on the main one. */
213 current_ui = main_ui;
214 (*async_handler_ptr->proc) (async_handler_ptr->client_data);
215 }
216
217 return any_ready;
218 }
219
220 /* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
221 Free the space allocated for it. */
222 void
223 delete_async_signal_handler (async_signal_handler ** async_handler_ptr)
224 {
225 async_signal_handler *prev_ptr;
226
227 if (sighandler_list.first_handler == (*async_handler_ptr))
228 {
229 sighandler_list.first_handler = (*async_handler_ptr)->next_handler;
230 if (sighandler_list.first_handler == NULL)
231 sighandler_list.last_handler = NULL;
232 }
233 else
234 {
235 prev_ptr = sighandler_list.first_handler;
236 while (prev_ptr && prev_ptr->next_handler != (*async_handler_ptr))
237 prev_ptr = prev_ptr->next_handler;
238 gdb_assert (prev_ptr);
239 prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
240 if (sighandler_list.last_handler == (*async_handler_ptr))
241 sighandler_list.last_handler = prev_ptr;
242 }
243 xfree ((*async_handler_ptr));
244 (*async_handler_ptr) = NULL;
245 }
246
247 /* See async-event.h. */
248
249 async_event_handler *
250 create_async_event_handler (async_event_handler_func *proc,
251 gdb_client_data client_data,
252 const char *name)
253 {
254 async_event_handler *h;
255
256 h = XNEW (struct async_event_handler);
257 h->ready = 0;
258 h->next_handler = NULL;
259 h->proc = proc;
260 h->client_data = client_data;
261 h->name = name;
262 if (async_event_handler_list.first_handler == NULL)
263 async_event_handler_list.first_handler = h;
264 else
265 async_event_handler_list.last_handler->next_handler = h;
266 async_event_handler_list.last_handler = h;
267 return h;
268 }
269
270 /* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
271 will be used by gdb_do_one_event. The caller will be whoever
272 created the event source, and wants to signal that the event is
273 ready to be handled. */
274 void
275 mark_async_event_handler (async_event_handler *async_handler_ptr)
276 {
277 async_handler_ptr->ready = 1;
278 }
279
280 /* See event-loop.h. */
281
282 void
283 clear_async_event_handler (async_event_handler *async_handler_ptr)
284 {
285 async_handler_ptr->ready = 0;
286 }
287
288 /* Check if asynchronous event handlers are ready, and call the
289 handler function for one that is. */
290
291 int
292 check_async_event_handlers ()
293 {
294 async_event_handler *async_handler_ptr;
295
296 for (async_handler_ptr = async_event_handler_list.first_handler;
297 async_handler_ptr != NULL;
298 async_handler_ptr = async_handler_ptr->next_handler)
299 {
300 if (async_handler_ptr->ready)
301 {
302 async_handler_ptr->ready = 0;
303 (*async_handler_ptr->proc) (async_handler_ptr->client_data);
304 return 1;
305 }
306 }
307
308 return 0;
309 }
310
311 /* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
312 Free the space allocated for it. */
313 void
314 delete_async_event_handler (async_event_handler **async_handler_ptr)
315 {
316 async_event_handler *prev_ptr;
317
318 if (async_event_handler_list.first_handler == *async_handler_ptr)
319 {
320 async_event_handler_list.first_handler
321 = (*async_handler_ptr)->next_handler;
322 if (async_event_handler_list.first_handler == NULL)
323 async_event_handler_list.last_handler = NULL;
324 }
325 else
326 {
327 prev_ptr = async_event_handler_list.first_handler;
328 while (prev_ptr && prev_ptr->next_handler != *async_handler_ptr)
329 prev_ptr = prev_ptr->next_handler;
330 gdb_assert (prev_ptr);
331 prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
332 if (async_event_handler_list.last_handler == (*async_handler_ptr))
333 async_event_handler_list.last_handler = prev_ptr;
334 }
335 xfree (*async_handler_ptr);
336 *async_handler_ptr = NULL;
337 }