17d62b00eSchristos /* Definitions used by the GDB event loop. 2*6881a400Schristos Copyright (C) 1999-2023 Free Software Foundation, Inc. 37d62b00eSchristos Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions. 47d62b00eSchristos 57d62b00eSchristos This file is part of GDB. 67d62b00eSchristos 77d62b00eSchristos This program is free software; you can redistribute it and/or modify 87d62b00eSchristos it under the terms of the GNU General Public License as published by 97d62b00eSchristos the Free Software Foundation; either version 3 of the License, or 107d62b00eSchristos (at your option) any later version. 117d62b00eSchristos 127d62b00eSchristos This program is distributed in the hope that it will be useful, 137d62b00eSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 147d62b00eSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 157d62b00eSchristos GNU General Public License for more details. 167d62b00eSchristos 177d62b00eSchristos You should have received a copy of the GNU General Public License 187d62b00eSchristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 197d62b00eSchristos 207d62b00eSchristos #ifndef EVENT_LOOP_H 217d62b00eSchristos #define EVENT_LOOP_H 227d62b00eSchristos 237d62b00eSchristos /* An event loop listens for events from multiple event sources. When 247d62b00eSchristos an event arrives, it is queued and processed by calling the 257d62b00eSchristos appropriate event handler. The event loop then continues to listen 267d62b00eSchristos for more events. An event loop completes when there are no event 277d62b00eSchristos sources to listen on. External event sources can be plugged into 287d62b00eSchristos the loop. 297d62b00eSchristos 307d62b00eSchristos There are 4 main components: 317d62b00eSchristos - a list of file descriptors to be monitored, GDB_NOTIFIER. 327d62b00eSchristos - a list of asynchronous event sources to be monitored, 337d62b00eSchristos ASYNC_EVENT_HANDLER_LIST. 347d62b00eSchristos - a list of events that have occurred, EVENT_QUEUE. 357d62b00eSchristos - a list of signal handling functions, SIGHANDLER_LIST. 367d62b00eSchristos 377d62b00eSchristos GDB_NOTIFIER keeps track of the file descriptor based event 387d62b00eSchristos sources. ASYNC_EVENT_HANDLER_LIST keeps track of asynchronous 397d62b00eSchristos event sources that are signalled by some component of gdb, usually 407d62b00eSchristos a target_ops instance. Event sources for gdb are currently the UI 417d62b00eSchristos and the target. Gdb communicates with the command line user 427d62b00eSchristos interface via the readline library and usually communicates with 437d62b00eSchristos remote targets via a serial port. Serial ports are represented in 447d62b00eSchristos GDB as file descriptors and select/poll calls. For native targets 457d62b00eSchristos instead, the communication varies across operating system debug 467d62b00eSchristos APIs, but usually consists of calls to ptrace and waits (via 477d62b00eSchristos signals) or calls to poll/select (via file descriptors). In the 487d62b00eSchristos current gdb, the code handling events related to the target resides 497d62b00eSchristos in wait_for_inferior for synchronous targets; or, for asynchronous 507d62b00eSchristos capable targets, by having the target register either a target 517d62b00eSchristos controlled file descriptor and/or an asynchronous event source in 527d62b00eSchristos the event loop, with the fetch_inferior_event function as the event 537d62b00eSchristos callback. In both the synchronous and asynchronous cases, usually 547d62b00eSchristos the target event is collected through the target_wait interface. 557d62b00eSchristos The target is free to install other event sources in the event loop 567d62b00eSchristos if it so requires. 577d62b00eSchristos 587d62b00eSchristos EVENT_QUEUE keeps track of the events that have happened during the 597d62b00eSchristos last iteration of the event loop, and need to be processed. An 607d62b00eSchristos event is represented by a procedure to be invoked in order to 617d62b00eSchristos process the event. The queue is scanned head to tail. If the 627d62b00eSchristos event of interest is a change of state in a file descriptor, then a 637d62b00eSchristos call to poll or select will be made to detect it. 647d62b00eSchristos 657d62b00eSchristos If the events generate signals, they are also queued by special 667d62b00eSchristos functions that are invoked through traditional signal handlers. 677d62b00eSchristos The actions to be taken is response to such events will be executed 687d62b00eSchristos when the SIGHANDLER_LIST is scanned, the next time through the 697d62b00eSchristos infinite loop. 707d62b00eSchristos 717d62b00eSchristos Corollary tasks are the creation and deletion of event sources. */ 727d62b00eSchristos 737d62b00eSchristos typedef void *gdb_client_data; 747d62b00eSchristos typedef void (handler_func) (int, gdb_client_data); 757d62b00eSchristos typedef void (timer_handler_func) (gdb_client_data); 767d62b00eSchristos 777d62b00eSchristos /* Exported functions from event-loop.c */ 787d62b00eSchristos 79*6881a400Schristos extern int gdb_do_one_event (int mstimeout = -1); 807d62b00eSchristos extern void delete_file_handler (int fd); 81*6881a400Schristos 82*6881a400Schristos /* Add a file handler/descriptor to the list of descriptors we are 83*6881a400Schristos interested in. 84*6881a400Schristos 85*6881a400Schristos FD is the file descriptor for the file/stream to be listened to. 86*6881a400Schristos 87*6881a400Schristos NAME is a user-friendly name for the handler. 88*6881a400Schristos 89*6881a400Schristos If IS_UI is set, this file descriptor is used for a user interface. */ 90*6881a400Schristos 917d62b00eSchristos extern void add_file_handler (int fd, handler_func *proc, 92*6881a400Schristos gdb_client_data client_data, 93*6881a400Schristos std::string &&name, bool is_ui = false); 94*6881a400Schristos 957d62b00eSchristos extern int create_timer (int milliseconds, 967d62b00eSchristos timer_handler_func *proc, 977d62b00eSchristos gdb_client_data client_data); 987d62b00eSchristos extern void delete_timer (int id); 997d62b00eSchristos 1007d62b00eSchristos /* Must be defined by client. */ 1017d62b00eSchristos 1027d62b00eSchristos extern void handle_event_loop_exception (const gdb_exception &); 1037d62b00eSchristos 1047d62b00eSchristos /* Must be defined by client. Returns true if any signal handler was 1057d62b00eSchristos ready. */ 1067d62b00eSchristos 1077d62b00eSchristos extern int invoke_async_signal_handlers (); 1087d62b00eSchristos 1097d62b00eSchristos /* Must be defined by client. Returns true if any event handler was 1107d62b00eSchristos ready. */ 1117d62b00eSchristos 1127d62b00eSchristos extern int check_async_event_handlers (); 1137d62b00eSchristos 114*6881a400Schristos enum class debug_event_loop_kind 115*6881a400Schristos { 116*6881a400Schristos OFF, 117*6881a400Schristos 118*6881a400Schristos /* Print all event-loop related messages, except events from user-interface 119*6881a400Schristos event sources. */ 120*6881a400Schristos ALL_EXCEPT_UI, 121*6881a400Schristos 122*6881a400Schristos /* Print all event-loop related messages. */ 123*6881a400Schristos ALL, 124*6881a400Schristos }; 125*6881a400Schristos 126*6881a400Schristos /* True if we are printing event loop debug statements. */ 127*6881a400Schristos extern debug_event_loop_kind debug_event_loop; 128*6881a400Schristos 129*6881a400Schristos /* Print an "event loop" debug statement. */ 130*6881a400Schristos 131*6881a400Schristos #define event_loop_debug_printf(fmt, ...) \ 132*6881a400Schristos debug_prefixed_printf_cond (debug_event_loop != debug_event_loop_kind::OFF, \ 133*6881a400Schristos "event-loop", fmt, ##__VA_ARGS__) 134*6881a400Schristos 135*6881a400Schristos /* Print an "event loop" debug statement that is know to come from a UI-related 136*6881a400Schristos event (e.g. calling the event handler for the fd of the CLI). */ 137*6881a400Schristos 138*6881a400Schristos #define event_loop_ui_debug_printf(is_ui, fmt, ...) \ 139*6881a400Schristos do \ 140*6881a400Schristos { \ 141*6881a400Schristos if (debug_event_loop == debug_event_loop_kind::ALL \ 142*6881a400Schristos || (debug_event_loop == debug_event_loop_kind::ALL_EXCEPT_UI \ 143*6881a400Schristos && !is_ui)) \ 144*6881a400Schristos debug_prefixed_printf ("event-loop", __func__, fmt, ##__VA_ARGS__); \ 145*6881a400Schristos } \ 146*6881a400Schristos while (0) 147*6881a400Schristos 1487d62b00eSchristos #endif /* EVENT_LOOP_H */ 149