Automatic date update in version.in
[binutils-gdb.git] / gdb / async-event.c
blob32b58652e585e7234779f59693f63530a37cffae
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 "async-event.h"
21 #include "ser-event.h"
22 #include "top.h"
23 #include "ui.h"
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.
32 Async_init_signals takes care of setting up such an
33 async_signal_handler for each interesting signal. */
35 struct async_signal_handler
37 /* If ready, call this handler from the main event loop, using
38 invoke_async_handler. */
39 int ready;
41 /* Pointer to next handler. */
42 struct async_signal_handler *next_handler;
44 /* Function to call to do the work. */
45 sig_handler_func *proc;
47 /* Argument to PROC. */
48 gdb_client_data client_data;
50 /* User-friendly name of this handler. */
51 const char *name;
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
62 /* If ready, call this handler from the main event loop, using
63 invoke_event_handler. */
64 int ready;
66 /* Pointer to next handler. */
67 struct async_event_handler *next_handler;
69 /* Function to call to do the work. */
70 async_event_handler_func *proc;
72 /* Argument to PROC. */
73 gdb_client_data client_data;
75 /* User-friendly name of this handler. */
76 const char *name;
79 /* All the async_signal_handlers gdb is interested in are kept onto
80 this list. */
81 static struct
83 /* Pointer to first in handler list. */
84 async_signal_handler *first_handler;
86 /* Pointer to last in handler list. */
87 async_signal_handler *last_handler;
89 sighandler_list;
91 /* All the async_event_handlers gdb is interested in are kept onto
92 this list. */
93 static struct
95 /* Pointer to first in handler list. */
96 async_event_handler *first_handler;
98 /* Pointer to last in handler list. */
99 async_event_handler *last_handler;
101 async_event_handler_list;
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;
108 /* Callback registered with ASYNC_SIGNAL_HANDLERS_SERIAL_EVENT. */
110 static void
111 async_signals_handler (int error, gdb_client_data client_data)
113 /* Do nothing. Handlers are run by invoke_async_signal_handlers
114 from instead. */
117 void
118 initialize_async_signal_handlers (void)
120 async_signal_handlers_serial_event = make_serial_event ();
122 add_file_handler (serial_event_fd (async_signal_handlers_serial_event),
123 async_signals_handler, NULL, "async-signals");
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)
139 async_signal_handler *async_handler_ptr;
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;
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)
162 if (debug_event_loop != debug_event_loop_kind::OFF)
164 /* This is called by signal handlers, so we print it "by hand" using
165 the async-signal-safe methods. */
166 const char head[] = ("[event-loop] mark_async_signal_handler: marking"
167 "async signal handler `");
168 gdb_stdlog->write_async_safe (head, strlen (head));
170 gdb_stdlog->write_async_safe (async_handler_ptr->name,
171 strlen (async_handler_ptr->name));
173 const char tail[] = "`\n";
174 gdb_stdlog->write_async_safe (tail, strlen (tail));
177 async_handler_ptr->ready = 1;
178 serial_event_set (async_signal_handlers_serial_event);
181 /* See event-loop.h. */
183 void
184 clear_async_signal_handler (async_signal_handler *async_handler_ptr)
186 event_loop_debug_printf ("clearing async signal handler `%s`",
187 async_handler_ptr->name);
188 async_handler_ptr->ready = 0;
191 /* See event-loop.h. */
194 async_signal_handler_is_marked (async_signal_handler *async_handler_ptr)
196 return async_handler_ptr->ready;
199 /* Call all the handlers that are ready. Returns true if any was
200 indeed ready. */
203 invoke_async_signal_handlers (void)
205 async_signal_handler *async_handler_ptr;
206 int any_ready = 0;
208 /* We're going to handle all pending signals, so no need to wake up
209 the event loop again the next time around. Note this must be
210 cleared _before_ calling the callbacks, to avoid races. */
211 serial_event_clear (async_signal_handlers_serial_event);
213 /* Invoke all ready handlers. */
215 while (1)
217 for (async_handler_ptr = sighandler_list.first_handler;
218 async_handler_ptr != NULL;
219 async_handler_ptr = async_handler_ptr->next_handler)
221 if (async_handler_ptr->ready)
222 break;
224 if (async_handler_ptr == NULL)
225 break;
226 any_ready = 1;
227 async_handler_ptr->ready = 0;
228 /* Async signal handlers have no connection to whichever was the
229 current UI, and thus always run on the main one. */
230 current_ui = main_ui;
231 event_loop_debug_printf ("invoking async signal handler `%s`",
232 async_handler_ptr->name);
233 (*async_handler_ptr->proc) (async_handler_ptr->client_data);
236 return any_ready;
239 /* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
240 Free the space allocated for it. */
241 void
242 delete_async_signal_handler (async_signal_handler ** async_handler_ptr)
244 async_signal_handler *prev_ptr;
246 if (sighandler_list.first_handler == (*async_handler_ptr))
248 sighandler_list.first_handler = (*async_handler_ptr)->next_handler;
249 if (sighandler_list.first_handler == NULL)
250 sighandler_list.last_handler = NULL;
252 else
254 prev_ptr = sighandler_list.first_handler;
255 while (prev_ptr && prev_ptr->next_handler != (*async_handler_ptr))
256 prev_ptr = prev_ptr->next_handler;
257 gdb_assert (prev_ptr);
258 prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
259 if (sighandler_list.last_handler == (*async_handler_ptr))
260 sighandler_list.last_handler = prev_ptr;
262 xfree ((*async_handler_ptr));
263 (*async_handler_ptr) = NULL;
266 /* See async-event.h. */
268 async_event_handler *
269 create_async_event_handler (async_event_handler_func *proc,
270 gdb_client_data client_data,
271 const char *name)
273 async_event_handler *h;
275 h = XNEW (struct async_event_handler);
276 h->ready = 0;
277 h->next_handler = NULL;
278 h->proc = proc;
279 h->client_data = client_data;
280 h->name = name;
281 if (async_event_handler_list.first_handler == NULL)
282 async_event_handler_list.first_handler = h;
283 else
284 async_event_handler_list.last_handler->next_handler = h;
285 async_event_handler_list.last_handler = h;
286 return h;
289 /* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
290 will be used by gdb_do_one_event. The caller will be whoever
291 created the event source, and wants to signal that the event is
292 ready to be handled. */
293 void
294 mark_async_event_handler (async_event_handler *async_handler_ptr)
296 event_loop_debug_printf ("marking async event handler `%s` "
297 "(previous state was %d)",
298 async_handler_ptr->name,
299 async_handler_ptr->ready);
300 async_handler_ptr->ready = 1;
303 /* See event-loop.h. */
305 void
306 clear_async_event_handler (async_event_handler *async_handler_ptr)
308 event_loop_debug_printf ("clearing async event handler `%s`",
309 async_handler_ptr->name);
310 async_handler_ptr->ready = 0;
313 /* See event-loop.h. */
315 bool
316 async_event_handler_marked (async_event_handler *handler)
318 return handler->ready;
321 /* Check if asynchronous event handlers are ready, and call the
322 handler function for one that is. */
325 check_async_event_handlers ()
327 async_event_handler *async_handler_ptr;
329 for (async_handler_ptr = async_event_handler_list.first_handler;
330 async_handler_ptr != NULL;
331 async_handler_ptr = async_handler_ptr->next_handler)
333 if (async_handler_ptr->ready)
335 event_loop_debug_printf ("invoking async event handler `%s`",
336 async_handler_ptr->name);
337 (*async_handler_ptr->proc) (async_handler_ptr->client_data);
338 return 1;
342 return 0;
345 /* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
346 Free the space allocated for it. */
347 void
348 delete_async_event_handler (async_event_handler **async_handler_ptr)
350 async_event_handler *prev_ptr;
352 if (async_event_handler_list.first_handler == *async_handler_ptr)
354 async_event_handler_list.first_handler
355 = (*async_handler_ptr)->next_handler;
356 if (async_event_handler_list.first_handler == NULL)
357 async_event_handler_list.last_handler = NULL;
359 else
361 prev_ptr = async_event_handler_list.first_handler;
362 while (prev_ptr && prev_ptr->next_handler != *async_handler_ptr)
363 prev_ptr = prev_ptr->next_handler;
364 gdb_assert (prev_ptr);
365 prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
366 if (async_event_handler_list.last_handler == (*async_handler_ptr))
367 async_event_handler_list.last_handler = prev_ptr;
369 xfree (*async_handler_ptr);
370 *async_handler_ptr = NULL;