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