/* Async events for the GDB event loop.
- Copyright (C) 1999-2019 Free Software Foundation, Inc.
+ Copyright (C) 1999-2022 Free Software Foundation, Inc.
This file is part of GDB.
Async_init_signals takes care of setting up such an
async_signal_handler for each interesting signal. */
-typedef struct async_signal_handler
- {
- int ready; /* If ready, call this handler
- from the main event loop, using
- invoke_async_handler. */
- struct async_signal_handler *next_handler; /* Ptr to next handler. */
- sig_handler_func *proc; /* Function to call to do the work. */
- gdb_client_data client_data; /* Argument to async_handler_func. */
- }
-async_signal_handler;
+struct async_signal_handler
+{
+ /* If ready, call this handler from the main event loop, using
+ invoke_async_handler. */
+ int ready;
+
+ /* Pointer to next handler. */
+ struct async_signal_handler *next_handler;
+
+ /* Function to call to do the work. */
+ sig_handler_func *proc;
+
+ /* Argument to PROC. */
+ gdb_client_data client_data;
+
+ /* User-friendly name of this handler. */
+ const char *name;
+};
/* PROC is a function to be invoked when the READY flag is set. This
happens when the event has been marked with
to an event will be carried out by PROC at a later time, within
process_event. This provides a deferred execution of event
handlers. */
-typedef struct async_event_handler
- {
- /* If ready, call this handler from the main event loop, using
- invoke_event_handler. */
- int ready;
+struct async_event_handler
+{
+ /* If ready, call this handler from the main event loop, using
+ invoke_event_handler. */
+ int ready;
- /* Point to next handler. */
- struct async_event_handler *next_handler;
+ /* Pointer to next handler. */
+ struct async_event_handler *next_handler;
- /* Function to call to do the work. */
- async_event_handler_func *proc;
+ /* Function to call to do the work. */
+ async_event_handler_func *proc;
- /* Argument to PROC. */
- gdb_client_data client_data;
- }
-async_event_handler;
+ /* Argument to PROC. */
+ gdb_client_data client_data;
+
+ /* User-friendly name of this handler. */
+ const char *name;
+};
/* All the async_signal_handlers gdb is interested in are kept onto
this list. */
static struct
- {
- /* Pointer to first in handler list. */
- async_signal_handler *first_handler;
+{
+ /* Pointer to first in handler list. */
+ async_signal_handler *first_handler;
- /* Pointer to last in handler list. */
- async_signal_handler *last_handler;
- }
+ /* Pointer to last in handler list. */
+ async_signal_handler *last_handler;
+}
sighandler_list;
/* All the async_event_handlers gdb is interested in are kept onto
this list. */
static struct
- {
- /* Pointer to first in handler list. */
- async_event_handler *first_handler;
+{
+ /* Pointer to first in handler list. */
+ async_event_handler *first_handler;
- /* Pointer to last in handler list. */
- async_event_handler *last_handler;
- }
+ /* Pointer to last in handler list. */
+ async_event_handler *last_handler;
+}
async_event_handler_list;
async_signal_handlers_serial_event = make_serial_event ();
add_file_handler (serial_event_fd (async_signal_handlers_serial_event),
- async_signals_handler, NULL);
+ async_signals_handler, NULL, "async-signals");
}
\f
whenever the handler is invoked. */
async_signal_handler *
create_async_signal_handler (sig_handler_func * proc,
- gdb_client_data client_data)
+ gdb_client_data client_data,
+ const char *name)
{
async_signal_handler *async_handler_ptr;
async_handler_ptr->next_handler = NULL;
async_handler_ptr->proc = proc;
async_handler_ptr->client_data = client_data;
+ async_handler_ptr->name = name;
if (sighandler_list.first_handler == NULL)
sighandler_list.first_handler = async_handler_ptr;
else
for some event. The caller of this function is the interrupt
handler associated with a signal. */
void
-mark_async_signal_handler (async_signal_handler * async_handler_ptr)
+mark_async_signal_handler (async_signal_handler *async_handler_ptr)
{
+ if (debug_event_loop != debug_event_loop_kind::OFF)
+ {
+ /* This is called by signal handlers, so we print it "by hand" using
+ the async-signal-safe methods. */
+ const char head[] = ("[event-loop] mark_async_signal_handler: marking"
+ "async signal handler `");
+ gdb_stdlog->write_async_safe (head, strlen (head));
+
+ gdb_stdlog->write_async_safe (async_handler_ptr->name,
+ strlen (async_handler_ptr->name));
+
+ const char tail[] = "`\n";
+ gdb_stdlog->write_async_safe (tail, strlen (tail));
+ }
+
async_handler_ptr->ready = 1;
serial_event_set (async_signal_handlers_serial_event);
}
void
clear_async_signal_handler (async_signal_handler *async_handler_ptr)
{
+ event_loop_debug_printf ("clearing async signal handler `%s`",
+ async_handler_ptr->name);
async_handler_ptr->ready = 0;
}
/* Async signal handlers have no connection to whichever was the
current UI, and thus always run on the main one. */
current_ui = main_ui;
+ event_loop_debug_printf ("invoking async signal handler `%s`",
+ async_handler_ptr->name);
(*async_handler_ptr->proc) (async_handler_ptr->client_data);
}
(*async_handler_ptr) = NULL;
}
-/* Create an asynchronous event handler, allocating memory for it.
- Return a pointer to the newly created handler. PROC is the
- function to call with CLIENT_DATA argument whenever the handler is
- invoked. */
+/* See async-event.h. */
+
async_event_handler *
create_async_event_handler (async_event_handler_func *proc,
- gdb_client_data client_data)
+ gdb_client_data client_data,
+ const char *name)
{
async_event_handler *h;
h->next_handler = NULL;
h->proc = proc;
h->client_data = client_data;
+ h->name = name;
if (async_event_handler_list.first_handler == NULL)
async_event_handler_list.first_handler = h;
else
void
mark_async_event_handler (async_event_handler *async_handler_ptr)
{
+ event_loop_debug_printf ("marking async event handler `%s`",
+ async_handler_ptr->name);
async_handler_ptr->ready = 1;
}
void
clear_async_event_handler (async_event_handler *async_handler_ptr)
{
+ event_loop_debug_printf ("clearing async event handler `%s`",
+ async_handler_ptr->name);
async_handler_ptr->ready = 0;
}
+/* See event-loop.h. */
+
+bool
+async_event_handler_marked (async_event_handler *handler)
+{
+ return handler->ready;
+}
+
/* Check if asynchronous event handlers are ready, and call the
handler function for one that is. */
{
if (async_handler_ptr->ready)
{
- async_handler_ptr->ready = 0;
+ event_loop_debug_printf ("invoking async event handler `%s`",
+ async_handler_ptr->name);
(*async_handler_ptr->proc) (async_handler_ptr->client_data);
return 1;
}