Automatic date update in version.in
[binutils-gdb.git] / gdb / async-event.c
blob7097c482fff2ffff71b302a6f15db3fc6abab716
1 /* Async events for the GDB event loop.
2 Copyright (C) 1999-2024 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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/>. */
19 #include "defs.h"
20 #include "async-event.h"
22 #include "ser-event.h"
23 #include "top.h"
24 #include "ui.h"
26 /* PROC is a function to be invoked when the READY flag is set. This
27 happens when there has been a signal and the corresponding signal
28 handler has 'triggered' this async_signal_handler for execution.
29 The actual work to be done in response to a signal will be carried
30 out by PROC at a later time, within process_event. This provides a
31 deferred execution of signal handlers.
33 Async_init_signals takes care of setting up such an
34 async_signal_handler for each interesting signal. */
36 struct async_signal_handler
38 /* If ready, call this handler from the main event loop, using
39 invoke_async_handler. */
40 int ready;
42 /* Pointer to next handler. */
43 struct async_signal_handler *next_handler;
45 /* Function to call to do the work. */
46 sig_handler_func *proc;
48 /* Argument to PROC. */
49 gdb_client_data client_data;
51 /* User-friendly name of this handler. */
52 const char *name;
55 /* PROC is a function to be invoked when the READY flag is set. This
56 happens when the event has been marked with
57 MARK_ASYNC_EVENT_HANDLER. The actual work to be done in response
58 to an event will be carried out by PROC at a later time, within
59 process_event. This provides a deferred execution of event
60 handlers. */
61 struct async_event_handler
63 /* If ready, call this handler from the main event loop, using
64 invoke_event_handler. */
65 int ready;
67 /* Pointer to next handler. */
68 struct async_event_handler *next_handler;
70 /* Function to call to do the work. */
71 async_event_handler_func *proc;
73 /* Argument to PROC. */
74 gdb_client_data client_data;
76 /* User-friendly name of this handler. */
77 const char *name;
80 /* All the async_signal_handlers gdb is interested in are kept onto
81 this list. */
82 static struct
84 /* Pointer to first in handler list. */
85 async_signal_handler *first_handler;
87 /* Pointer to last in handler list. */
88 async_signal_handler *last_handler;
90 sighandler_list;
92 /* All the async_event_handlers gdb is interested in are kept onto
93 this list. */
94 static struct
96 /* Pointer to first in handler list. */
97 async_event_handler *first_handler;
99 /* Pointer to last in handler list. */
100 async_event_handler *last_handler;
102 async_event_handler_list;
105 /* This event is signalled whenever an asynchronous handler needs to
106 defer an action to the event loop. */
107 static struct serial_event *async_signal_handlers_serial_event;
109 /* Callback registered with ASYNC_SIGNAL_HANDLERS_SERIAL_EVENT. */
111 static void
112 async_signals_handler (int error, gdb_client_data client_data)
114 /* Do nothing. Handlers are run by invoke_async_signal_handlers
115 from instead. */
118 void
119 initialize_async_signal_handlers (void)
121 async_signal_handlers_serial_event = make_serial_event ();
123 add_file_handler (serial_event_fd (async_signal_handlers_serial_event),
124 async_signals_handler, NULL, "async-signals");
129 /* Create an asynchronous handler, allocating memory for it.
130 Return a pointer to the newly created handler.
131 This pointer will be used to invoke the handler by
132 invoke_async_signal_handler.
133 PROC is the function to call with CLIENT_DATA argument
134 whenever the handler is invoked. */
135 async_signal_handler *
136 create_async_signal_handler (sig_handler_func * proc,
137 gdb_client_data client_data,
138 const char *name)
140 async_signal_handler *async_handler_ptr;
142 async_handler_ptr = XNEW (async_signal_handler);
143 async_handler_ptr->ready = 0;
144 async_handler_ptr->next_handler = NULL;
145 async_handler_ptr->proc = proc;
146 async_handler_ptr->client_data = client_data;
147 async_handler_ptr->name = name;
148 if (sighandler_list.first_handler == NULL)
149 sighandler_list.first_handler = async_handler_ptr;
150 else
151 sighandler_list.last_handler->next_handler = async_handler_ptr;
152 sighandler_list.last_handler = async_handler_ptr;
153 return async_handler_ptr;
156 /* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
157 will be used when the handlers are invoked, after we have waited
158 for some event. The caller of this function is the interrupt
159 handler associated with a signal. */
160 void
161 mark_async_signal_handler (async_signal_handler *async_handler_ptr)
163 if (debug_event_loop != debug_event_loop_kind::OFF)
165 /* This is called by signal handlers, so we print it "by hand" using
166 the async-signal-safe methods. */
167 const char head[] = ("[event-loop] mark_async_signal_handler: marking"
168 "async signal handler `");
169 gdb_stdlog->write_async_safe (head, strlen (head));
171 gdb_stdlog->write_async_safe (async_handler_ptr->name,
172 strlen (async_handler_ptr->name));
174 const char tail[] = "`\n";
175 gdb_stdlog->write_async_safe (tail, strlen (tail));
178 async_handler_ptr->ready = 1;
179 serial_event_set (async_signal_handlers_serial_event);
182 /* See event-loop.h. */
184 void
185 clear_async_signal_handler (async_signal_handler *async_handler_ptr)
187 event_loop_debug_printf ("clearing async signal handler `%s`",
188 async_handler_ptr->name);
189 async_handler_ptr->ready = 0;
192 /* See event-loop.h. */
195 async_signal_handler_is_marked (async_signal_handler *async_handler_ptr)
197 return async_handler_ptr->ready;
200 /* Call all the handlers that are ready. Returns true if any was
201 indeed ready. */
204 invoke_async_signal_handlers (void)
206 async_signal_handler *async_handler_ptr;
207 int any_ready = 0;
209 /* We're going to handle all pending signals, so no need to wake up
210 the event loop again the next time around. Note this must be
211 cleared _before_ calling the callbacks, to avoid races. */
212 serial_event_clear (async_signal_handlers_serial_event);
214 /* Invoke all ready handlers. */
216 while (1)
218 for (async_handler_ptr = sighandler_list.first_handler;
219 async_handler_ptr != NULL;
220 async_handler_ptr = async_handler_ptr->next_handler)
222 if (async_handler_ptr->ready)
223 break;
225 if (async_handler_ptr == NULL)
226 break;
227 any_ready = 1;
228 async_handler_ptr->ready = 0;
229 /* Async signal handlers have no connection to whichever was the
230 current UI, and thus always run on the main one. */
231 current_ui = main_ui;
232 event_loop_debug_printf ("invoking async signal handler `%s`",
233 async_handler_ptr->name);
234 (*async_handler_ptr->proc) (async_handler_ptr->client_data);
237 return any_ready;
240 /* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
241 Free the space allocated for it. */
242 void
243 delete_async_signal_handler (async_signal_handler ** async_handler_ptr)
245 async_signal_handler *prev_ptr;
247 if (sighandler_list.first_handler == (*async_handler_ptr))
249 sighandler_list.first_handler = (*async_handler_ptr)->next_handler;
250 if (sighandler_list.first_handler == NULL)
251 sighandler_list.last_handler = NULL;
253 else
255 prev_ptr = sighandler_list.first_handler;
256 while (prev_ptr && prev_ptr->next_handler != (*async_handler_ptr))
257 prev_ptr = prev_ptr->next_handler;
258 gdb_assert (prev_ptr);
259 prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
260 if (sighandler_list.last_handler == (*async_handler_ptr))
261 sighandler_list.last_handler = prev_ptr;
263 xfree ((*async_handler_ptr));
264 (*async_handler_ptr) = NULL;
267 /* See async-event.h. */
269 async_event_handler *
270 create_async_event_handler (async_event_handler_func *proc,
271 gdb_client_data client_data,
272 const char *name)
274 async_event_handler *h;
276 h = XNEW (struct async_event_handler);
277 h->ready = 0;
278 h->next_handler = NULL;
279 h->proc = proc;
280 h->client_data = client_data;
281 h->name = name;
282 if (async_event_handler_list.first_handler == NULL)
283 async_event_handler_list.first_handler = h;
284 else
285 async_event_handler_list.last_handler->next_handler = h;
286 async_event_handler_list.last_handler = h;
287 return h;
290 /* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
291 will be used by gdb_do_one_event. The caller will be whoever
292 created the event source, and wants to signal that the event is
293 ready to be handled. */
294 void
295 mark_async_event_handler (async_event_handler *async_handler_ptr)
297 event_loop_debug_printf ("marking async event handler `%s` "
298 "(previous state was %d)",
299 async_handler_ptr->name,
300 async_handler_ptr->ready);
301 async_handler_ptr->ready = 1;
304 /* See event-loop.h. */
306 void
307 clear_async_event_handler (async_event_handler *async_handler_ptr)
309 event_loop_debug_printf ("clearing async event handler `%s`",
310 async_handler_ptr->name);
311 async_handler_ptr->ready = 0;
314 /* See event-loop.h. */
316 bool
317 async_event_handler_marked (async_event_handler *handler)
319 return handler->ready;
322 /* Check if asynchronous event handlers are ready, and call the
323 handler function for one that is. */
326 check_async_event_handlers ()
328 async_event_handler *async_handler_ptr;
330 for (async_handler_ptr = async_event_handler_list.first_handler;
331 async_handler_ptr != NULL;
332 async_handler_ptr = async_handler_ptr->next_handler)
334 if (async_handler_ptr->ready)
336 event_loop_debug_printf ("invoking async event handler `%s`",
337 async_handler_ptr->name);
338 (*async_handler_ptr->proc) (async_handler_ptr->client_data);
339 return 1;
343 return 0;
346 /* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
347 Free the space allocated for it. */
348 void
349 delete_async_event_handler (async_event_handler **async_handler_ptr)
351 async_event_handler *prev_ptr;
353 if (async_event_handler_list.first_handler == *async_handler_ptr)
355 async_event_handler_list.first_handler
356 = (*async_handler_ptr)->next_handler;
357 if (async_event_handler_list.first_handler == NULL)
358 async_event_handler_list.last_handler = NULL;
360 else
362 prev_ptr = async_event_handler_list.first_handler;
363 while (prev_ptr && prev_ptr->next_handler != *async_handler_ptr)
364 prev_ptr = prev_ptr->next_handler;
365 gdb_assert (prev_ptr);
366 prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
367 if (async_event_handler_list.last_handler == (*async_handler_ptr))
368 async_event_handler_list.last_handler = prev_ptr;
370 xfree (*async_handler_ptr);
371 *async_handler_ptr = NULL;