18dffb485Schristos /* Definitions used by the GDB event loop. 2*5ba1f45fSchristos Copyright (C) 1999-2024 Free Software Foundation, Inc. 38dffb485Schristos Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions. 48dffb485Schristos 58dffb485Schristos This file is part of GDB. 68dffb485Schristos 78dffb485Schristos This program is free software; you can redistribute it and/or modify 88dffb485Schristos it under the terms of the GNU General Public License as published by 98dffb485Schristos the Free Software Foundation; either version 3 of the License, or 108dffb485Schristos (at your option) any later version. 118dffb485Schristos 128dffb485Schristos This program is distributed in the hope that it will be useful, 138dffb485Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 148dffb485Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 158dffb485Schristos GNU General Public License for more details. 168dffb485Schristos 178dffb485Schristos You should have received a copy of the GNU General Public License 188dffb485Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 198dffb485Schristos 208dffb485Schristos #ifndef EVENT_LOOP_H 218dffb485Schristos #define EVENT_LOOP_H 228dffb485Schristos 238dffb485Schristos /* An event loop listens for events from multiple event sources. When 248dffb485Schristos an event arrives, it is queued and processed by calling the 258dffb485Schristos appropriate event handler. The event loop then continues to listen 268dffb485Schristos for more events. An event loop completes when there are no event 278dffb485Schristos sources to listen on. External event sources can be plugged into 288dffb485Schristos the loop. 298dffb485Schristos 308dffb485Schristos There are 4 main components: 318dffb485Schristos - a list of file descriptors to be monitored, GDB_NOTIFIER. 328dffb485Schristos - a list of asynchronous event sources to be monitored, 338dffb485Schristos ASYNC_EVENT_HANDLER_LIST. 348dffb485Schristos - a list of events that have occurred, EVENT_QUEUE. 358dffb485Schristos - a list of signal handling functions, SIGHANDLER_LIST. 368dffb485Schristos 378dffb485Schristos GDB_NOTIFIER keeps track of the file descriptor based event 388dffb485Schristos sources. ASYNC_EVENT_HANDLER_LIST keeps track of asynchronous 398dffb485Schristos event sources that are signalled by some component of gdb, usually 408dffb485Schristos a target_ops instance. Event sources for gdb are currently the UI 418dffb485Schristos and the target. Gdb communicates with the command line user 428dffb485Schristos interface via the readline library and usually communicates with 438dffb485Schristos remote targets via a serial port. Serial ports are represented in 448dffb485Schristos GDB as file descriptors and select/poll calls. For native targets 458dffb485Schristos instead, the communication varies across operating system debug 468dffb485Schristos APIs, but usually consists of calls to ptrace and waits (via 478dffb485Schristos signals) or calls to poll/select (via file descriptors). In the 488dffb485Schristos current gdb, the code handling events related to the target resides 498dffb485Schristos in wait_for_inferior for synchronous targets; or, for asynchronous 508dffb485Schristos capable targets, by having the target register either a target 518dffb485Schristos controlled file descriptor and/or an asynchronous event source in 528dffb485Schristos the event loop, with the fetch_inferior_event function as the event 538dffb485Schristos callback. In both the synchronous and asynchronous cases, usually 548dffb485Schristos the target event is collected through the target_wait interface. 558dffb485Schristos The target is free to install other event sources in the event loop 568dffb485Schristos if it so requires. 578dffb485Schristos 588dffb485Schristos EVENT_QUEUE keeps track of the events that have happened during the 598dffb485Schristos last iteration of the event loop, and need to be processed. An 608dffb485Schristos event is represented by a procedure to be invoked in order to 618dffb485Schristos process the event. The queue is scanned head to tail. If the 628dffb485Schristos event of interest is a change of state in a file descriptor, then a 638dffb485Schristos call to poll or select will be made to detect it. 648dffb485Schristos 658dffb485Schristos If the events generate signals, they are also queued by special 668dffb485Schristos functions that are invoked through traditional signal handlers. 678dffb485Schristos The actions to be taken is response to such events will be executed 688dffb485Schristos when the SIGHANDLER_LIST is scanned, the next time through the 698dffb485Schristos infinite loop. 708dffb485Schristos 718dffb485Schristos Corollary tasks are the creation and deletion of event sources. */ 728dffb485Schristos 738dffb485Schristos typedef void *gdb_client_data; 748dffb485Schristos typedef void (handler_func) (int, gdb_client_data); 758dffb485Schristos typedef void (timer_handler_func) (gdb_client_data); 768dffb485Schristos 778dffb485Schristos /* Exported functions from event-loop.c */ 788dffb485Schristos 794b169a6bSchristos extern int gdb_do_one_event (int mstimeout = -1); 808dffb485Schristos extern void delete_file_handler (int fd); 814b169a6bSchristos 824b169a6bSchristos /* Add a file handler/descriptor to the list of descriptors we are 834b169a6bSchristos interested in. 844b169a6bSchristos 854b169a6bSchristos FD is the file descriptor for the file/stream to be listened to. 864b169a6bSchristos 874b169a6bSchristos NAME is a user-friendly name for the handler. 884b169a6bSchristos 894b169a6bSchristos If IS_UI is set, this file descriptor is used for a user interface. */ 904b169a6bSchristos 918dffb485Schristos extern void add_file_handler (int fd, handler_func *proc, 924b169a6bSchristos gdb_client_data client_data, 934b169a6bSchristos std::string &&name, bool is_ui = false); 944b169a6bSchristos 958dffb485Schristos extern int create_timer (int milliseconds, 968dffb485Schristos timer_handler_func *proc, 978dffb485Schristos gdb_client_data client_data); 988dffb485Schristos extern void delete_timer (int id); 998dffb485Schristos 1008dffb485Schristos /* Must be defined by client. */ 1018dffb485Schristos 1028dffb485Schristos extern void handle_event_loop_exception (const gdb_exception &); 1038dffb485Schristos 1048dffb485Schristos /* Must be defined by client. Returns true if any signal handler was 1058dffb485Schristos ready. */ 1068dffb485Schristos 1078dffb485Schristos extern int invoke_async_signal_handlers (); 1088dffb485Schristos 1098dffb485Schristos /* Must be defined by client. Returns true if any event handler was 1108dffb485Schristos ready. */ 1118dffb485Schristos 1128dffb485Schristos extern int check_async_event_handlers (); 1138dffb485Schristos 1144b169a6bSchristos enum class debug_event_loop_kind 1154b169a6bSchristos { 1164b169a6bSchristos OFF, 1174b169a6bSchristos 1184b169a6bSchristos /* Print all event-loop related messages, except events from user-interface 1194b169a6bSchristos event sources. */ 1204b169a6bSchristos ALL_EXCEPT_UI, 1214b169a6bSchristos 1224b169a6bSchristos /* Print all event-loop related messages. */ 1234b169a6bSchristos ALL, 1244b169a6bSchristos }; 1254b169a6bSchristos 1264b169a6bSchristos /* True if we are printing event loop debug statements. */ 1274b169a6bSchristos extern debug_event_loop_kind debug_event_loop; 1284b169a6bSchristos 1294b169a6bSchristos /* Print an "event loop" debug statement. */ 1304b169a6bSchristos 1314b169a6bSchristos #define event_loop_debug_printf(fmt, ...) \ 1324b169a6bSchristos debug_prefixed_printf_cond (debug_event_loop != debug_event_loop_kind::OFF, \ 1334b169a6bSchristos "event-loop", fmt, ##__VA_ARGS__) 1344b169a6bSchristos 1354b169a6bSchristos /* Print an "event loop" debug statement that is know to come from a UI-related 1364b169a6bSchristos event (e.g. calling the event handler for the fd of the CLI). */ 1374b169a6bSchristos 1384b169a6bSchristos #define event_loop_ui_debug_printf(is_ui, fmt, ...) \ 1394b169a6bSchristos do \ 1404b169a6bSchristos { \ 1414b169a6bSchristos if (debug_event_loop == debug_event_loop_kind::ALL \ 1424b169a6bSchristos || (debug_event_loop == debug_event_loop_kind::ALL_EXCEPT_UI \ 1434b169a6bSchristos && !is_ui)) \ 1444b169a6bSchristos debug_prefixed_printf ("event-loop", __func__, fmt, ##__VA_ARGS__); \ 1454b169a6bSchristos } \ 1464b169a6bSchristos while (0) 1474b169a6bSchristos 1488dffb485Schristos #endif /* EVENT_LOOP_H */ 149