Introduce async-event.[ch]

This patch splits out some gdb-specific code from event-loop, into new
files async-event.[ch].  Strictly speaking this code could perhaps be
put into gdbsupport/, but because gdbserver does not currently use it,
it seemed better, for size reasons, to split it out.

gdb/ChangeLog
2020-04-13  Tom Tromey  <tom@tromey.com>

	* tui/tui-win.c: Include async-event.h.
	* remote.c: Include async-event.h.
	* remote-notif.c: Include async-event.h.
	* record-full.c: Include async-event.h.
	* record-btrace.c: Include async-event.h.
	* infrun.c: Include async-event.h.
	* event-top.c: Include async-event.h.
	* event-loop.h: Move some declarations to async-event.h.
	* event-loop.c: Don't include ser-event.h or top.h.  Move some
	code to async-event.c.
	* async-event.h: New file.
	* async-event.c: New file.
	* Makefile.in (COMMON_SFILES): Add async-event.c.
	(HFILES_NO_SRCDIR): Add async-event.h.
This commit is contained in:
Tom Tromey 2020-04-13 12:42:59 -06:00 committed by Tom Tromey
parent c1cd3163d9
commit 93b54c8ed3
13 changed files with 430 additions and 345 deletions

View File

@ -1,3 +1,20 @@
2020-04-13 Tom Tromey <tom@tromey.com>
* tui/tui-win.c: Include async-event.h.
* remote.c: Include async-event.h.
* remote-notif.c: Include async-event.h.
* record-full.c: Include async-event.h.
* record-btrace.c: Include async-event.h.
* infrun.c: Include async-event.h.
* event-top.c: Include async-event.h.
* event-loop.h: Move some declarations to async-event.h.
* event-loop.c: Don't include ser-event.h or top.h. Move some
code to async-event.c.
* async-event.h: New file.
* async-event.c: New file.
* Makefile.in (COMMON_SFILES): Add async-event.c.
(HFILES_NO_SRCDIR): Add async-event.h.
2020-04-13 Tom Tromey <tom@tromey.com>
* utils.c (flush_streams): New function.

View File

@ -955,6 +955,7 @@ COMMON_SFILES = \
alloc.c \
annotate.c \
arch-utils.c \
async-event.c \
auto-load.c \
auxv.c \
ax-gdb.c \
@ -1212,6 +1213,7 @@ HFILES_NO_SRCDIR = \
arm-linux-tdep.h \
arm-nbsd-tdep.h \
arm-tdep.h \
async-event.h \
auto-load.h \
auxv.h \
ax.h \

325
gdb/async-event.c Normal file
View File

@ -0,0 +1,325 @@
/* Async events for the GDB event loop.
Copyright (C) 1999-2019 Free Software Foundation, Inc.
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/>. */
#include "defs.h"
#include "async-event.h"
#include "ser-event.h"
#include "top.h"
/* PROC is a function to be invoked when the READY flag is set. This
happens when there has been a signal and the corresponding signal
handler has 'triggered' this async_signal_handler for execution.
The actual work to be done in response to a signal will be carried
out by PROC at a later time, within process_event. This provides a
deferred execution of signal handlers.
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;
/* PROC is a function to be invoked when the READY flag is set. This
happens when the event has been marked with
MARK_ASYNC_EVENT_HANDLER. The actual work to be done in response
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;
/* Point to next handler. */
struct async_event_handler *next_handler;
/* Function to call to do the work. */
async_event_handler_func *proc;
/* Argument to PROC. */
gdb_client_data client_data;
}
async_event_handler;
/* 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 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 last in handler list. */
async_event_handler *last_handler;
}
async_event_handler_list;
/* This event is signalled whenever an asynchronous handler needs to
defer an action to the event loop. */
static struct serial_event *async_signal_handlers_serial_event;
/* Callback registered with ASYNC_SIGNAL_HANDLERS_SERIAL_EVENT. */
static void
async_signals_handler (int error, gdb_client_data client_data)
{
/* Do nothing. Handlers are run by invoke_async_signal_handlers
from instead. */
}
void
initialize_async_signal_handlers (void)
{
async_signal_handlers_serial_event = make_serial_event ();
add_file_handler (serial_event_fd (async_signal_handlers_serial_event),
async_signals_handler, NULL);
}
/* Create an asynchronous handler, allocating memory for it.
Return a pointer to the newly created handler.
This pointer will be used to invoke the handler by
invoke_async_signal_handler.
PROC is the function to call with CLIENT_DATA argument
whenever the handler is invoked. */
async_signal_handler *
create_async_signal_handler (sig_handler_func * proc,
gdb_client_data client_data)
{
async_signal_handler *async_handler_ptr;
async_handler_ptr = XNEW (async_signal_handler);
async_handler_ptr->ready = 0;
async_handler_ptr->next_handler = NULL;
async_handler_ptr->proc = proc;
async_handler_ptr->client_data = client_data;
if (sighandler_list.first_handler == NULL)
sighandler_list.first_handler = async_handler_ptr;
else
sighandler_list.last_handler->next_handler = async_handler_ptr;
sighandler_list.last_handler = async_handler_ptr;
return async_handler_ptr;
}
/* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
will be used when the handlers are invoked, after we have waited
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)
{
async_handler_ptr->ready = 1;
serial_event_set (async_signal_handlers_serial_event);
}
/* See event-loop.h. */
void
clear_async_signal_handler (async_signal_handler *async_handler_ptr)
{
async_handler_ptr->ready = 0;
}
/* See event-loop.h. */
int
async_signal_handler_is_marked (async_signal_handler *async_handler_ptr)
{
return async_handler_ptr->ready;
}
/* Call all the handlers that are ready. Returns true if any was
indeed ready. */
int
invoke_async_signal_handlers (void)
{
async_signal_handler *async_handler_ptr;
int any_ready = 0;
/* We're going to handle all pending signals, so no need to wake up
the event loop again the next time around. Note this must be
cleared _before_ calling the callbacks, to avoid races. */
serial_event_clear (async_signal_handlers_serial_event);
/* Invoke all ready handlers. */
while (1)
{
for (async_handler_ptr = sighandler_list.first_handler;
async_handler_ptr != NULL;
async_handler_ptr = async_handler_ptr->next_handler)
{
if (async_handler_ptr->ready)
break;
}
if (async_handler_ptr == NULL)
break;
any_ready = 1;
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;
(*async_handler_ptr->proc) (async_handler_ptr->client_data);
}
return any_ready;
}
/* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
Free the space allocated for it. */
void
delete_async_signal_handler (async_signal_handler ** async_handler_ptr)
{
async_signal_handler *prev_ptr;
if (sighandler_list.first_handler == (*async_handler_ptr))
{
sighandler_list.first_handler = (*async_handler_ptr)->next_handler;
if (sighandler_list.first_handler == NULL)
sighandler_list.last_handler = NULL;
}
else
{
prev_ptr = sighandler_list.first_handler;
while (prev_ptr && prev_ptr->next_handler != (*async_handler_ptr))
prev_ptr = prev_ptr->next_handler;
gdb_assert (prev_ptr);
prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
if (sighandler_list.last_handler == (*async_handler_ptr))
sighandler_list.last_handler = prev_ptr;
}
xfree ((*async_handler_ptr));
(*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. */
async_event_handler *
create_async_event_handler (async_event_handler_func *proc,
gdb_client_data client_data)
{
async_event_handler *h;
h = XNEW (struct async_event_handler);
h->ready = 0;
h->next_handler = NULL;
h->proc = proc;
h->client_data = client_data;
if (async_event_handler_list.first_handler == NULL)
async_event_handler_list.first_handler = h;
else
async_event_handler_list.last_handler->next_handler = h;
async_event_handler_list.last_handler = h;
return h;
}
/* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
will be used by gdb_do_one_event. The caller will be whoever
created the event source, and wants to signal that the event is
ready to be handled. */
void
mark_async_event_handler (async_event_handler *async_handler_ptr)
{
async_handler_ptr->ready = 1;
}
/* See event-loop.h. */
void
clear_async_event_handler (async_event_handler *async_handler_ptr)
{
async_handler_ptr->ready = 0;
}
/* Check if asynchronous event handlers are ready, and call the
handler function for one that is. */
int
check_async_event_handlers ()
{
async_event_handler *async_handler_ptr;
for (async_handler_ptr = async_event_handler_list.first_handler;
async_handler_ptr != NULL;
async_handler_ptr = async_handler_ptr->next_handler)
{
if (async_handler_ptr->ready)
{
async_handler_ptr->ready = 0;
(*async_handler_ptr->proc) (async_handler_ptr->client_data);
return 1;
}
}
return 0;
}
/* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
Free the space allocated for it. */
void
delete_async_event_handler (async_event_handler **async_handler_ptr)
{
async_event_handler *prev_ptr;
if (async_event_handler_list.first_handler == *async_handler_ptr)
{
async_event_handler_list.first_handler
= (*async_handler_ptr)->next_handler;
if (async_event_handler_list.first_handler == NULL)
async_event_handler_list.last_handler = NULL;
}
else
{
prev_ptr = async_event_handler_list.first_handler;
while (prev_ptr && prev_ptr->next_handler != *async_handler_ptr)
prev_ptr = prev_ptr->next_handler;
gdb_assert (prev_ptr);
prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
if (async_event_handler_list.last_handler == (*async_handler_ptr))
async_event_handler_list.last_handler = prev_ptr;
}
xfree (*async_handler_ptr);
*async_handler_ptr = NULL;
}

71
gdb/async-event.h Normal file
View File

@ -0,0 +1,71 @@
/* Async events for the GDB event loop.
Copyright (C) 1999-2019 Free Software Foundation, Inc.
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 ASYNC_EVENT_H
#define ASYNC_EVENT_H
#include "event-loop.h"
struct async_signal_handler;
struct async_event_handler;
typedef void (sig_handler_func) (gdb_client_data);
typedef void (async_event_handler_func) (gdb_client_data);
extern struct async_signal_handler *
create_async_signal_handler (sig_handler_func *proc,
gdb_client_data client_data);
extern void delete_async_signal_handler (struct async_signal_handler **);
/* Call the handler from HANDLER the next time through the event
loop. */
extern void mark_async_signal_handler (struct async_signal_handler *handler);
/* Returns true if HANDLER is marked ready. */
extern int
async_signal_handler_is_marked (struct async_signal_handler *handler);
/* Mark HANDLER as NOT ready. */
extern void clear_async_signal_handler (struct async_signal_handler *handler);
/* Create and register an asynchronous event source in the event loop,
and set PROC as its callback. CLIENT_DATA is passed as argument to
PROC upon its invocation. Returns a pointer to an opaque structure
used to mark as ready and to later delete this event source from
the event loop. */
extern struct async_event_handler *
create_async_event_handler (async_event_handler_func *proc,
gdb_client_data client_data);
/* Remove the event source pointed by HANDLER_PTR created by
CREATE_ASYNC_EVENT_HANDLER from the event loop, and release it. */
extern void
delete_async_event_handler (struct async_event_handler **handler_ptr);
/* Call the handler from HANDLER the next time through the event
loop. */
extern void mark_async_event_handler (struct async_event_handler *handler);
/* Mark the handler (ASYNC_HANDLER_PTR) as NOT ready. */
extern void clear_async_event_handler (struct async_event_handler *handler);
extern void initialize_async_signal_handlers (void);
#endif /* ASYNC_EVENT_H */

View File

@ -19,8 +19,6 @@
#include "defs.h"
#include "event-loop.h"
#include "event-top.h"
#include "ser-event.h"
#include <chrono>
@ -35,7 +33,6 @@
#include <sys/types.h>
#include "gdbsupport/gdb_sys_time.h"
#include "gdbsupport/gdb_select.h"
#include "top.h"
/* Tell create_file_handler what events we are interested in.
This is used by the select version of the event loop. */
@ -60,50 +57,6 @@ typedef struct file_handler
}
file_handler;
/* PROC is a function to be invoked when the READY flag is set. This
happens when there has been a signal and the corresponding signal
handler has 'triggered' this async_signal_handler for execution.
The actual work to be done in response to a signal will be carried
out by PROC at a later time, within process_event. This provides a
deferred execution of signal handlers.
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;
/* PROC is a function to be invoked when the READY flag is set. This
happens when the event has been marked with
MARK_ASYNC_EVENT_HANDLER. The actual work to be done in response
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;
/* Point to next handler. */
struct async_event_handler *next_handler;
/* Function to call to do the work. */
async_event_handler_func *proc;
/* Argument to PROC. */
gdb_client_data client_data;
}
async_event_handler;
/* Gdb_notifier is just a list of file descriptors gdb is interested in.
These are the input file descriptor, and the target file
descriptor. We have two flavors of the notifier, one for platforms
@ -198,61 +151,12 @@ static struct
}
timer_list;
/* 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 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 last in handler list. */
async_event_handler *last_handler;
}
async_event_handler_list;
static int invoke_async_signal_handlers (void);
static void create_file_handler (int fd, int mask, handler_func *proc,
gdb_client_data client_data);
static int check_async_event_handlers (void);
static int gdb_wait_for_event (int);
static int update_wait_timeout (void);
static int poll_timers (void);
/* This event is signalled whenever an asynchronous handler needs to
defer an action to the event loop. */
static struct serial_event *async_signal_handlers_serial_event;
/* Callback registered with ASYNC_SIGNAL_HANDLERS_SERIAL_EVENT. */
static void
async_signals_handler (int error, gdb_client_data client_data)
{
/* Do nothing. Handlers are run by invoke_async_signal_handlers
from instead. */
}
void
initialize_async_signal_handlers (void)
{
async_signal_handlers_serial_event = make_serial_event ();
add_file_handler (serial_event_fd (async_signal_handlers_serial_event),
async_signals_handler, NULL);
}
/* Process one high level event. If nothing is ready at this time,
wait for something to happen (via gdb_wait_for_event), then process
it. Returns >0 if something was done otherwise returns <0 (this
@ -800,216 +704,6 @@ gdb_wait_for_event (int block)
return 0;
}
/* Create an asynchronous handler, allocating memory for it.
Return a pointer to the newly created handler.
This pointer will be used to invoke the handler by
invoke_async_signal_handler.
PROC is the function to call with CLIENT_DATA argument
whenever the handler is invoked. */
async_signal_handler *
create_async_signal_handler (sig_handler_func * proc,
gdb_client_data client_data)
{
async_signal_handler *async_handler_ptr;
async_handler_ptr = XNEW (async_signal_handler);
async_handler_ptr->ready = 0;
async_handler_ptr->next_handler = NULL;
async_handler_ptr->proc = proc;
async_handler_ptr->client_data = client_data;
if (sighandler_list.first_handler == NULL)
sighandler_list.first_handler = async_handler_ptr;
else
sighandler_list.last_handler->next_handler = async_handler_ptr;
sighandler_list.last_handler = async_handler_ptr;
return async_handler_ptr;
}
/* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
will be used when the handlers are invoked, after we have waited
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)
{
async_handler_ptr->ready = 1;
serial_event_set (async_signal_handlers_serial_event);
}
/* See event-loop.h. */
void
clear_async_signal_handler (async_signal_handler *async_handler_ptr)
{
async_handler_ptr->ready = 0;
}
/* See event-loop.h. */
int
async_signal_handler_is_marked (async_signal_handler *async_handler_ptr)
{
return async_handler_ptr->ready;
}
/* Call all the handlers that are ready. Returns true if any was
indeed ready. */
static int
invoke_async_signal_handlers (void)
{
async_signal_handler *async_handler_ptr;
int any_ready = 0;
/* We're going to handle all pending signals, so no need to wake up
the event loop again the next time around. Note this must be
cleared _before_ calling the callbacks, to avoid races. */
serial_event_clear (async_signal_handlers_serial_event);
/* Invoke all ready handlers. */
while (1)
{
for (async_handler_ptr = sighandler_list.first_handler;
async_handler_ptr != NULL;
async_handler_ptr = async_handler_ptr->next_handler)
{
if (async_handler_ptr->ready)
break;
}
if (async_handler_ptr == NULL)
break;
any_ready = 1;
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;
(*async_handler_ptr->proc) (async_handler_ptr->client_data);
}
return any_ready;
}
/* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
Free the space allocated for it. */
void
delete_async_signal_handler (async_signal_handler ** async_handler_ptr)
{
async_signal_handler *prev_ptr;
if (sighandler_list.first_handler == (*async_handler_ptr))
{
sighandler_list.first_handler = (*async_handler_ptr)->next_handler;
if (sighandler_list.first_handler == NULL)
sighandler_list.last_handler = NULL;
}
else
{
prev_ptr = sighandler_list.first_handler;
while (prev_ptr && prev_ptr->next_handler != (*async_handler_ptr))
prev_ptr = prev_ptr->next_handler;
gdb_assert (prev_ptr);
prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
if (sighandler_list.last_handler == (*async_handler_ptr))
sighandler_list.last_handler = prev_ptr;
}
xfree ((*async_handler_ptr));
(*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. */
async_event_handler *
create_async_event_handler (async_event_handler_func *proc,
gdb_client_data client_data)
{
async_event_handler *h;
h = XNEW (struct async_event_handler);
h->ready = 0;
h->next_handler = NULL;
h->proc = proc;
h->client_data = client_data;
if (async_event_handler_list.first_handler == NULL)
async_event_handler_list.first_handler = h;
else
async_event_handler_list.last_handler->next_handler = h;
async_event_handler_list.last_handler = h;
return h;
}
/* Mark the handler (ASYNC_HANDLER_PTR) as ready. This information
will be used by gdb_do_one_event. The caller will be whoever
created the event source, and wants to signal that the event is
ready to be handled. */
void
mark_async_event_handler (async_event_handler *async_handler_ptr)
{
async_handler_ptr->ready = 1;
}
/* See event-loop.h. */
void
clear_async_event_handler (async_event_handler *async_handler_ptr)
{
async_handler_ptr->ready = 0;
}
/* Check if asynchronous event handlers are ready, and call the
handler function for one that is. */
static int
check_async_event_handlers (void)
{
async_event_handler *async_handler_ptr;
for (async_handler_ptr = async_event_handler_list.first_handler;
async_handler_ptr != NULL;
async_handler_ptr = async_handler_ptr->next_handler)
{
if (async_handler_ptr->ready)
{
async_handler_ptr->ready = 0;
(*async_handler_ptr->proc) (async_handler_ptr->client_data);
return 1;
}
}
return 0;
}
/* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
Free the space allocated for it. */
void
delete_async_event_handler (async_event_handler **async_handler_ptr)
{
async_event_handler *prev_ptr;
if (async_event_handler_list.first_handler == *async_handler_ptr)
{
async_event_handler_list.first_handler
= (*async_handler_ptr)->next_handler;
if (async_event_handler_list.first_handler == NULL)
async_event_handler_list.last_handler = NULL;
}
else
{
prev_ptr = async_event_handler_list.first_handler;
while (prev_ptr && prev_ptr->next_handler != *async_handler_ptr)
prev_ptr = prev_ptr->next_handler;
gdb_assert (prev_ptr);
prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
if (async_event_handler_list.last_handler == (*async_handler_ptr))
async_event_handler_list.last_handler = prev_ptr;
}
xfree (*async_handler_ptr);
*async_handler_ptr = NULL;
}
/* Create a timer that will expire in MS milliseconds from now. When
the timer is ready, PROC will be executed. At creation, the timer
is added to the timers queue. This queue is kept sorted in order

View File

@ -71,11 +71,7 @@
Corollary tasks are the creation and deletion of event sources. */
typedef void *gdb_client_data;
struct async_signal_handler;
struct async_event_handler;
typedef void (handler_func) (int, gdb_client_data);
typedef void (sig_handler_func) (gdb_client_data);
typedef void (async_event_handler_func) (gdb_client_data);
typedef void (timer_handler_func) (gdb_client_data);
/* Exported functions from event-loop.c */
@ -84,50 +80,23 @@ extern int gdb_do_one_event (void);
extern void delete_file_handler (int fd);
extern void add_file_handler (int fd, handler_func *proc,
gdb_client_data client_data);
extern struct async_signal_handler *
create_async_signal_handler (sig_handler_func *proc,
gdb_client_data client_data);
extern void delete_async_signal_handler (struct async_signal_handler **);
extern int create_timer (int milliseconds,
timer_handler_func *proc,
gdb_client_data client_data);
extern void delete_timer (int id);
/* Call the handler from HANDLER the next time through the event
loop. */
extern void mark_async_signal_handler (struct async_signal_handler *handler);
/* Must be defined by client. */
/* Returns true if HANDLER is marked ready. */
extern void handle_event_loop_exception (const gdb_exception &);
extern int
async_signal_handler_is_marked (struct async_signal_handler *handler);
/* Must be defined by client. Returns true if any signal handler was
ready. */
/* Mark HANDLER as NOT ready. */
extern int invoke_async_signal_handlers ();
extern void clear_async_signal_handler (struct async_signal_handler *handler);
/* Must be defined by client. Returns true if any event handler was
ready. */
/* Create and register an asynchronous event source in the event loop,
and set PROC as its callback. CLIENT_DATA is passed as argument to
PROC upon its invocation. Returns a pointer to an opaque structure
used to mark as ready and to later delete this event source from
the event loop. */
extern struct async_event_handler *
create_async_event_handler (async_event_handler_func *proc,
gdb_client_data client_data);
/* Remove the event source pointed by HANDLER_PTR created by
CREATE_ASYNC_EVENT_HANDLER from the event loop, and release it. */
extern void
delete_async_event_handler (struct async_event_handler **handler_ptr);
/* Call the handler from HANDLER the next time through the event
loop. */
extern void mark_async_event_handler (struct async_event_handler *handler);
/* Mark the handler (ASYNC_HANDLER_PTR) as NOT ready. */
extern void clear_async_event_handler (struct async_event_handler *handler);
extern void initialize_async_signal_handlers (void);
extern int check_async_event_handlers ();
#endif /* EVENT_LOOP_H */

View File

@ -41,6 +41,7 @@
#include "ser-event.h"
#include "gdbsupport/gdb_select.h"
#include "gdbsupport/gdb-sigmask.h"
#include "async-event.h"
/* readline include files. */
#include "readline/readline.h"

View File

@ -66,6 +66,7 @@
#include "gdbsupport/forward-scope-exit.h"
#include "gdbsupport/gdb_select.h"
#include <unordered_map>
#include "async-event.h"
/* Prototypes for local functions */

View File

@ -42,6 +42,7 @@
#include <algorithm>
#include "gdbarch.h"
#include "cli/cli-style.h"
#include "async-event.h"
static const target_info record_btrace_target_info = {
"record-btrace",

View File

@ -38,6 +38,7 @@
#include "infrun.h"
#include "gdbsupport/gdb_unlinker.h"
#include "gdbsupport/byte-vector.h"
#include "async-event.h"
#include <signal.h>

View File

@ -40,6 +40,7 @@
#include "inferior.h"
#include "infrun.h"
#include "gdbcmd.h"
#include "async-event.h"
bool notif_debug = false;

View File

@ -77,6 +77,7 @@
#include "gdbsupport/byte-vector.h"
#include <algorithm>
#include <unordered_map>
#include "async-event.h"
/* The remote target. */

View File

@ -35,6 +35,7 @@
#include "source.h"
#include "event-loop.h"
#include "gdbcmd.h"
#include "async-event.h"
#include "tui/tui.h"
#include "tui/tui-io.h"