1/* Async events for the GDB event loop. 2 Copyright (C) 1999-2023 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 35struct 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. */ 60struct 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. */ 81static 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} 89sighandler_list; 90 91/* All the async_event_handlers gdb is interested in are kept onto 92 this list. */ 93static 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} 101async_event_handler_list; 102 103 104/* This event is signalled whenever an asynchronous handler needs to 105 defer an action to the event loop. */ 106static struct serial_event *async_signal_handlers_serial_event; 107 108/* Callback registered with ASYNC_SIGNAL_HANDLERS_SERIAL_EVENT. */ 109 110static void 111async_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 117void 118initialize_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 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. */ 134async_signal_handler * 135create_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. */ 159void 160mark_async_signal_handler (async_signal_handler *async_handler_ptr) 161{ 162 if (debug_event_loop != debug_event_loop_kind::OFF) 163 { 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)); 169 170 gdb_stdlog->write_async_safe (async_handler_ptr->name, 171 strlen (async_handler_ptr->name)); 172 173 const char tail[] = "`\n"; 174 gdb_stdlog->write_async_safe (tail, strlen (tail)); 175 } 176 177 async_handler_ptr->ready = 1; 178 serial_event_set (async_signal_handlers_serial_event); 179} 180 181/* See event-loop.h. */ 182 183void 184clear_async_signal_handler (async_signal_handler *async_handler_ptr) 185{ 186 event_loop_debug_printf ("clearing async signal handler `%s`", 187 async_handler_ptr->name); 188 async_handler_ptr->ready = 0; 189} 190 191/* See event-loop.h. */ 192 193int 194async_signal_handler_is_marked (async_signal_handler *async_handler_ptr) 195{ 196 return async_handler_ptr->ready; 197} 198 199/* Call all the handlers that are ready. Returns true if any was 200 indeed ready. */ 201 202int 203invoke_async_signal_handlers (void) 204{ 205 async_signal_handler *async_handler_ptr; 206 int any_ready = 0; 207 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); 212 213 /* Invoke all ready handlers. */ 214 215 while (1) 216 { 217 for (async_handler_ptr = sighandler_list.first_handler; 218 async_handler_ptr != NULL; 219 async_handler_ptr = async_handler_ptr->next_handler) 220 { 221 if (async_handler_ptr->ready) 222 break; 223 } 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); 234 } 235 236 return any_ready; 237} 238 239/* Delete an asynchronous handler (ASYNC_HANDLER_PTR). 240 Free the space allocated for it. */ 241void 242delete_async_signal_handler (async_signal_handler ** async_handler_ptr) 243{ 244 async_signal_handler *prev_ptr; 245 246 if (sighandler_list.first_handler == (*async_handler_ptr)) 247 { 248 sighandler_list.first_handler = (*async_handler_ptr)->next_handler; 249 if (sighandler_list.first_handler == NULL) 250 sighandler_list.last_handler = NULL; 251 } 252 else 253 { 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; 261 } 262 xfree ((*async_handler_ptr)); 263 (*async_handler_ptr) = NULL; 264} 265 266/* See async-event.h. */ 267 268async_event_handler * 269create_async_event_handler (async_event_handler_func *proc, 270 gdb_client_data client_data, 271 const char *name) 272{ 273 async_event_handler *h; 274 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; 287} 288 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. */ 293void 294mark_async_event_handler (async_event_handler *async_handler_ptr) 295{ 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; 301} 302 303/* See event-loop.h. */ 304 305void 306clear_async_event_handler (async_event_handler *async_handler_ptr) 307{ 308 event_loop_debug_printf ("clearing async event handler `%s`", 309 async_handler_ptr->name); 310 async_handler_ptr->ready = 0; 311} 312 313/* See event-loop.h. */ 314 315bool 316async_event_handler_marked (async_event_handler *handler) 317{ 318 return handler->ready; 319} 320 321/* Check if asynchronous event handlers are ready, and call the 322 handler function for one that is. */ 323 324int 325check_async_event_handlers () 326{ 327 async_event_handler *async_handler_ptr; 328 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) 332 { 333 if (async_handler_ptr->ready) 334 { 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; 339 } 340 } 341 342 return 0; 343} 344 345/* Delete an asynchronous handler (ASYNC_HANDLER_PTR). 346 Free the space allocated for it. */ 347void 348delete_async_event_handler (async_event_handler **async_handler_ptr) 349{ 350 async_event_handler *prev_ptr; 351 352 if (async_event_handler_list.first_handler == *async_handler_ptr) 353 { 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; 358 } 359 else 360 { 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; 368 } 369 xfree (*async_handler_ptr); 370 *async_handler_ptr = NULL; 371} 372