xref: /netbsd-src/external/gpl3/gdb/dist/gdbsupport/event-loop.h (revision 5ba1f45f2a09259cc846f20c7c5501604d633c90)
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