aboutsummaryrefslogtreecommitdiff
path: root/gdb/event-loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/event-loop.c')
-rw-r--r--gdb/event-loop.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/gdb/event-loop.c b/gdb/event-loop.c
index 0e1cb2b..052d535 100644
--- a/gdb/event-loop.c
+++ b/gdb/event-loop.c
@@ -21,6 +21,7 @@
#include "event-loop.h"
#include "event-top.h"
#include "queue.h"
+#include "ser-event.h"
#ifdef HAVE_POLL
#if defined (HAVE_POLL_H)
@@ -262,6 +263,28 @@ 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
@@ -905,6 +928,7 @@ 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. */
@@ -925,13 +949,19 @@ async_signal_handler_is_marked (async_signal_handler *async_handler_ptr)
/* 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;
- /* Invoke ready handlers. */
+ /* 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)
{