/* Definitions used by the GDB event loop.
   Copyright (C) 1999-2025 Free Software Foundation, Inc.
   Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef GDBSUPPORT_EVENT_LOOP_H
#define GDBSUPPORT_EVENT_LOOP_H

/* An event loop listens for events from multiple event sources.  When
   an event arrives, it is queued and processed by calling the
   appropriate event handler.  The event loop then continues to listen
   for more events.  An event loop completes when there are no event
   sources to listen on.  External event sources can be plugged into
   the loop.

   There are 4 main components:
   - a list of file descriptors to be monitored, GDB_NOTIFIER.
   - a list of asynchronous event sources to be monitored,
     ASYNC_EVENT_HANDLER_LIST.
   - a list of events that have occurred, EVENT_QUEUE.
   - a list of signal handling functions, SIGHANDLER_LIST.

   GDB_NOTIFIER keeps track of the file descriptor based event
   sources.  ASYNC_EVENT_HANDLER_LIST keeps track of asynchronous
   event sources that are signalled by some component of gdb, usually
   a target_ops instance.  Event sources for gdb are currently the UI
   and the target.  Gdb communicates with the command line user
   interface via the readline library and usually communicates with
   remote targets via a serial port.  Serial ports are represented in
   GDB as file descriptors and select/poll calls.  For native targets
   instead, the communication varies across operating system debug
   APIs, but usually consists of calls to ptrace and waits (via
   signals) or calls to poll/select (via file descriptors).  In the
   current gdb, the code handling events related to the target resides
   in wait_for_inferior for synchronous targets; or, for asynchronous
   capable targets, by having the target register either a target
   controlled file descriptor and/or an asynchronous event source in
   the event loop, with the fetch_inferior_event function as the event
   callback.  In both the synchronous and asynchronous cases, usually
   the target event is collected through the target_wait interface.
   The target is free to install other event sources in the event loop
   if it so requires.

   EVENT_QUEUE keeps track of the events that have happened during the
   last iteration of the event loop, and need to be processed.  An
   event is represented by a procedure to be invoked in order to
   process the event.  The queue is scanned head to tail.  If the
   event of interest is a change of state in a file descriptor, then a
   call to poll or select will be made to detect it.

   If the events generate signals, they are also queued by special
   functions that are invoked through traditional signal handlers.
   The actions to be taken is response to such events will be executed
   when the SIGHANDLER_LIST is scanned, the next time through the
   infinite loop.

   Corollary tasks are the creation and deletion of event sources.  */

typedef void *gdb_client_data;
typedef void (handler_func) (int, gdb_client_data);
typedef void (timer_handler_func) (gdb_client_data);

/* Exported functions from event-loop.c */

extern int gdb_do_one_event (int mstimeout = -1);
extern void delete_file_handler (int fd);

/* Add a file handler/descriptor to the list of descriptors we are
   interested in.

   FD is the file descriptor for the file/stream to be listened to.

   NAME is a user-friendly name for the handler.

   If IS_UI is set, this file descriptor is used for a user interface.  */

extern void add_file_handler (int fd, handler_func *proc,
			      gdb_client_data client_data,
			      std::string &&name, bool is_ui = false);

extern int create_timer (int milliseconds, 
			 timer_handler_func *proc, 
			 gdb_client_data client_data);
extern void delete_timer (int id);

/* Must be defined by client.  */

extern void handle_event_loop_exception (const gdb_exception &);

/* Must be defined by client.  Returns true if any signal handler was
   ready.  */

extern int invoke_async_signal_handlers ();

/* Must be defined by client.  Returns true if any event handler was
   ready.  */

extern int check_async_event_handlers ();

enum class debug_event_loop_kind
{
  OFF,

  /* Print all event-loop related messages, except events from user-interface
     event sources.  */
  ALL_EXCEPT_UI,

  /* Print all event-loop related messages.  */
  ALL,
};

/* True if we are printing event loop debug statements.  */
extern debug_event_loop_kind debug_event_loop;

/* Print an "event loop" debug statement.  */

#define event_loop_debug_printf(fmt, ...) \
  debug_prefixed_printf_cond (debug_event_loop != debug_event_loop_kind::OFF, \
			      "event-loop", fmt, ##__VA_ARGS__)

/* Print an "event loop" debug statement that is know to come from a UI-related
   event (e.g. calling the event handler for the fd of the CLI).  */

#define event_loop_ui_debug_printf(is_ui, fmt, ...) \
  do \
    { \
      if (debug_event_loop == debug_event_loop_kind::ALL \
	  || (debug_event_loop == debug_event_loop_kind::ALL_EXCEPT_UI \
	      && !is_ui)) \
	debug_prefixed_printf ("event-loop", __func__, fmt, ##__VA_ARGS__); \
    } \
  while (0)

#endif /* GDBSUPPORT_EVENT_LOOP_H */
