aboutsummaryrefslogtreecommitdiff
path: root/gdbserver
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2020-04-13 12:42:59 -0600
committerTom Tromey <tromey@adacore.com>2020-04-13 14:10:04 -0600
commit55d7aec85e81c4597e94ebcc8b85f20a1d439bd0 (patch)
tree664fe7b861844fbe141d01768c38e2f6b033399e /gdbserver
parente487f9949ab654b20da8ac01b8311ae956136e5e (diff)
downloadfsf-binutils-gdb-55d7aec85e81c4597e94ebcc8b85f20a1d439bd0.zip
fsf-binutils-gdb-55d7aec85e81c4597e94ebcc8b85f20a1d439bd0.tar.gz
fsf-binutils-gdb-55d7aec85e81c4597e94ebcc8b85f20a1d439bd0.tar.bz2
Switch gdbserver to gdbsupport event loop
This changes gdbserver to use the gdbserver event loop, removing the ancient fork. gdbserver/ChangeLog 2020-04-13 Tom Tromey <tom@tromey.com> * server.h (handle_serial_event, handle_target_event): Update. * server.c: Don't call initialize_event_loop. (keep_processing_events): New global. (handle_serial_event): Return void. Set keep_processing_events. (handle_target_event): Return void. (start_event_loop): Move from event-loop.c. Rewrite. * remote-utils.c (handle_accept_event): Return void. (reset_readchar): Use delete_timer. (process_remaining): Return void. (reschedule): Use create_timer. * event-loop.h: Remove. * event-loop.cc: Remove. * Makefile.in (OBS): Use gdbsupport/event-loop.o, not event-loop.o.
Diffstat (limited to 'gdbserver')
-rw-r--r--gdbserver/ChangeLog16
-rw-r--r--gdbserver/Makefile.in1
-rw-r--r--gdbserver/event-loop.cc567
-rw-r--r--gdbserver/event-loop.h36
-rw-r--r--gdbserver/remote-utils.cc18
-rw-r--r--gdbserver/server.cc44
-rw-r--r--gdbserver/server.h6
7 files changed, 60 insertions, 628 deletions
diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog
index 309cae3..1d0fbb8 100644
--- a/gdbserver/ChangeLog
+++ b/gdbserver/ChangeLog
@@ -1,5 +1,21 @@
2020-04-13 Tom Tromey <tom@tromey.com>
+ * server.h (handle_serial_event, handle_target_event): Update.
+ * server.c: Don't call initialize_event_loop.
+ (keep_processing_events): New global.
+ (handle_serial_event): Return void. Set keep_processing_events.
+ (handle_target_event): Return void.
+ (start_event_loop): Move from event-loop.c. Rewrite.
+ * remote-utils.c (handle_accept_event): Return void.
+ (reset_readchar): Use delete_timer.
+ (process_remaining): Return void.
+ (reschedule): Use create_timer.
+ * event-loop.h: Remove.
+ * event-loop.cc: Remove.
+ * Makefile.in (OBS): Use gdbsupport/event-loop.o, not event-loop.o.
+
+2020-04-13 Tom Tromey <tom@tromey.com>
+
* server.c (invoke_async_signal_handlers)
(check_async_event_handlers, flush_streams, gdb_select): New
functions.
diff --git a/gdbserver/Makefile.in b/gdbserver/Makefile.in
index 8c35c16..417a530 100644
--- a/gdbserver/Makefile.in
+++ b/gdbserver/Makefile.in
@@ -241,7 +241,6 @@ OBS = \
ax.o \
debug.o \
dll.o \
- event-loop.o \
hostio.o \
inferiors.o \
mem-break.o \
diff --git a/gdbserver/event-loop.cc b/gdbserver/event-loop.cc
deleted file mode 100644
index 8827e8a..0000000
--- a/gdbserver/event-loop.cc
+++ /dev/null
@@ -1,567 +0,0 @@
-/* Event loop machinery for the remote server for GDB.
- Copyright (C) 1999-2020 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/>. */
-
-/* Based on src/gdb/event-loop.c. */
-
-#include "server.h"
-
-#include <sys/types.h>
-#include "gdbsupport/gdb_sys_time.h"
-
-#ifdef USE_WIN32API
-#include <windows.h>
-#include <io.h>
-#endif
-
-#include <unistd.h>
-#include <queue>
-
-typedef int (event_handler_func) (gdb_fildes_t);
-
-/* Tell create_file_handler what events we are interested in. */
-
-#define GDB_READABLE (1<<1)
-#define GDB_WRITABLE (1<<2)
-#define GDB_EXCEPTION (1<<3)
-
-/* Events are queued by on the event_queue and serviced later
- on by do_one_event. An event can be, for instance, a file
- descriptor becoming ready to be read. Servicing an event simply
- means that the procedure PROC will be called. We have 2 queues,
- one for file handlers that we listen to in the event loop, and one
- for the file handlers+events that are ready. The procedure PROC
- associated with each event is always the same (handle_file_event).
- Its duty is to invoke the handler associated with the file
- descriptor whose state change generated the event, plus doing other
- cleanups and such. */
-
-struct gdb_event
- {
- /* Procedure to call to service this event. */
- event_handler_func *proc;
-
- /* File descriptor that is ready. */
- gdb_fildes_t fd;
- };
-
-/* Information about each file descriptor we register with the event
- loop. */
-
-typedef struct file_handler
- {
- /* File descriptor. */
- gdb_fildes_t fd;
-
- /* Events we want to monitor. */
- int mask;
-
- /* Events that have been seen since the last time. */
- int ready_mask;
-
- /* Procedure to call when fd is ready. */
- handler_func *proc;
-
- /* Argument to pass to proc. */
- gdb_client_data client_data;
-
- /* Was an error detected on this fd? */
- int error;
-
- /* Next registered file descriptor. */
- struct file_handler *next_file;
- }
-file_handler;
-
-typedef gdb::unique_xmalloc_ptr<gdb_event> gdb_event_up;
-
-static std::queue<gdb_event_up, std::list<gdb_event_up>> event_queue;
-
-/* Gdb_notifier is just a list of file descriptors gdb is interested
- in. These are the input file descriptor, and the target file
- descriptor. Each of the elements in the gdb_notifier list is
- basically a description of what kind of events gdb is interested
- in, for each fd. */
-
-static struct
- {
- /* Ptr to head of file handler list. */
- file_handler *first_file_handler;
-
- /* Masks to be used in the next call to select. Bits are set in
- response to calls to create_file_handler. */
- fd_set check_masks[3];
-
- /* What file descriptors were found ready by select. */
- fd_set ready_masks[3];
-
- /* Number of valid bits (highest fd value + 1). (for select) */
- int num_fds;
- }
-gdb_notifier;
-
-/* Callbacks are just routines that are executed before waiting for the
- next event. In GDB this is struct gdb_timer. We don't need timers
- so rather than copy all that complexity in gdbserver, we provide what
- we need, but we do so in a way that if/when the day comes that we need
- that complexity, it'll be easier to add - replace callbacks with timers
- and use a delta of zero (which is all gdb currently uses timers for anyway).
-
- PROC will be executed before gdbserver goes to sleep to wait for the
- next event. */
-
-struct callback_event
- {
- int id;
- callback_handler_func *proc;
- gdb_client_data data;
- struct callback_event *next;
- };
-
-/* Table of registered callbacks. */
-
-static struct
- {
- struct callback_event *first;
- struct callback_event *last;
-
- /* Id of the last callback created. */
- int num_callbacks;
- }
-callback_list;
-
-void
-initialize_event_loop (void)
-{
-}
-
-/* Process one event. If an event was processed, 1 is returned
- otherwise 0 is returned. Scan the queue from head to tail,
- processing therefore the high priority events first, by invoking
- the associated event handler procedure. */
-
-static int
-process_event (void)
-{
- /* Let's get rid of the event from the event queue. We need to
- do this now because while processing the event, since the
- proc function could end up jumping out to the caller of this
- function. In that case, we would have on the event queue an
- event which has been processed, but not deleted. */
- if (!event_queue.empty ())
- {
- gdb_event_up event_ptr = std::move (event_queue.front ());
- event_queue.pop ();
-
- event_handler_func *proc = event_ptr->proc;
- gdb_fildes_t fd = event_ptr->fd;
-
- /* Now call the procedure associated with the event. */
- if ((*proc) (fd))
- return -1;
- return 1;
- }
-
- /* This is the case if there are no event on the event queue. */
- return 0;
-}
-
-/* Append PROC to the callback list.
- The result is the "id" of the callback that can be passed back to
- delete_callback_event. */
-
-int
-append_callback_event (callback_handler_func *proc, gdb_client_data data)
-{
- struct callback_event *event_ptr = XNEW (struct callback_event);
-
- event_ptr->id = callback_list.num_callbacks++;
- event_ptr->proc = proc;
- event_ptr->data = data;
- event_ptr->next = NULL;
- if (callback_list.first == NULL)
- callback_list.first = event_ptr;
- if (callback_list.last != NULL)
- callback_list.last->next = event_ptr;
- callback_list.last = event_ptr;
- return event_ptr->id;
-}
-
-/* Delete callback ID.
- It is not an error callback ID doesn't exist. */
-
-void
-delete_callback_event (int id)
-{
- struct callback_event **p;
-
- for (p = &callback_list.first; *p != NULL; p = &(*p)->next)
- {
- struct callback_event *event_ptr = *p;
-
- if (event_ptr->id == id)
- {
- *p = event_ptr->next;
- if (event_ptr == callback_list.last)
- callback_list.last = NULL;
- free (event_ptr);
- break;
- }
- }
-}
-
-/* Run the next callback.
- The result is 1 if a callback was called and event processing
- should continue, -1 if the callback wants the event loop to exit,
- and 0 if there are no more callbacks. */
-
-static int
-process_callback (void)
-{
- struct callback_event *event_ptr;
-
- event_ptr = callback_list.first;
- if (event_ptr != NULL)
- {
- callback_handler_func *proc = event_ptr->proc;
- gdb_client_data data = event_ptr->data;
-
- /* Remove the event before calling PROC,
- more events may get added by PROC. */
- callback_list.first = event_ptr->next;
- if (callback_list.first == NULL)
- callback_list.last = NULL;
- free (event_ptr);
- if ((*proc) (data))
- return -1;
- return 1;
- }
-
- return 0;
-}
-
-/* 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. MASK is a combination of READABLE, WRITABLE,
- EXCEPTION. PROC is the procedure that will be called when an event
- occurs for FD. CLIENT_DATA is the argument to pass to PROC. */
-
-static void
-create_file_handler (gdb_fildes_t fd, int mask, handler_func *proc,
- gdb_client_data client_data)
-{
- file_handler *file_ptr;
-
- /* Do we already have a file handler for this file? (We may be
- changing its associated procedure). */
- for (file_ptr = gdb_notifier.first_file_handler;
- file_ptr != NULL;
- file_ptr = file_ptr->next_file)
- if (file_ptr->fd == fd)
- break;
-
- /* It is a new file descriptor. Add it to the list. Otherwise,
- just change the data associated with it. */
- if (file_ptr == NULL)
- {
- file_ptr = XNEW (struct file_handler);
- file_ptr->fd = fd;
- file_ptr->ready_mask = 0;
- file_ptr->next_file = gdb_notifier.first_file_handler;
- gdb_notifier.first_file_handler = file_ptr;
-
- if (mask & GDB_READABLE)
- FD_SET (fd, &gdb_notifier.check_masks[0]);
- else
- FD_CLR (fd, &gdb_notifier.check_masks[0]);
-
- if (mask & GDB_WRITABLE)
- FD_SET (fd, &gdb_notifier.check_masks[1]);
- else
- FD_CLR (fd, &gdb_notifier.check_masks[1]);
-
- if (mask & GDB_EXCEPTION)
- FD_SET (fd, &gdb_notifier.check_masks[2]);
- else
- FD_CLR (fd, &gdb_notifier.check_masks[2]);
-
- if (gdb_notifier.num_fds <= fd)
- gdb_notifier.num_fds = fd + 1;
- }
-
- file_ptr->proc = proc;
- file_ptr->client_data = client_data;
- file_ptr->mask = mask;
-}
-
-/* Wrapper function for create_file_handler. */
-
-void
-add_file_handler (gdb_fildes_t fd,
- handler_func *proc, gdb_client_data client_data)
-{
- create_file_handler (fd, GDB_READABLE | GDB_EXCEPTION, proc, client_data);
-}
-
-/* Remove the file descriptor FD from the list of monitored fd's:
- i.e. we don't care anymore about events on the FD. */
-
-void
-delete_file_handler (gdb_fildes_t fd)
-{
- file_handler *file_ptr, *prev_ptr = NULL;
- int i;
-
- /* Find the entry for the given file. */
-
- for (file_ptr = gdb_notifier.first_file_handler;
- file_ptr != NULL;
- file_ptr = file_ptr->next_file)
- if (file_ptr->fd == fd)
- break;
-
- if (file_ptr == NULL)
- return;
-
- if (file_ptr->mask & GDB_READABLE)
- FD_CLR (fd, &gdb_notifier.check_masks[0]);
- if (file_ptr->mask & GDB_WRITABLE)
- FD_CLR (fd, &gdb_notifier.check_masks[1]);
- if (file_ptr->mask & GDB_EXCEPTION)
- FD_CLR (fd, &gdb_notifier.check_masks[2]);
-
- /* Find current max fd. */
-
- if ((fd + 1) == gdb_notifier.num_fds)
- {
- gdb_notifier.num_fds--;
- for (i = gdb_notifier.num_fds; i; i--)
- {
- if (FD_ISSET (i - 1, &gdb_notifier.check_masks[0])
- || FD_ISSET (i - 1, &gdb_notifier.check_masks[1])
- || FD_ISSET (i - 1, &gdb_notifier.check_masks[2]))
- break;
- }
- gdb_notifier.num_fds = i;
- }
-
- /* Deactivate the file descriptor, by clearing its mask, so that it
- will not fire again. */
-
- file_ptr->mask = 0;
-
- /* Get rid of the file handler in the file handler list. */
- if (file_ptr == gdb_notifier.first_file_handler)
- gdb_notifier.first_file_handler = file_ptr->next_file;
- else
- {
- for (prev_ptr = gdb_notifier.first_file_handler;
- prev_ptr->next_file != file_ptr;
- prev_ptr = prev_ptr->next_file)
- ;
- prev_ptr->next_file = file_ptr->next_file;
- }
- free (file_ptr);
-}
-
-/* Handle the given event by calling the procedure associated to the
- corresponding file handler. Called by process_event indirectly,
- through event_ptr->proc. EVENT_FILE_DESC is file descriptor of the
- event in the front of the event queue. */
-
-static int
-handle_file_event (gdb_fildes_t event_file_desc)
-{
- file_handler *file_ptr;
- int mask;
-
- /* Search the file handler list to find one that matches the fd in
- the event. */
- for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
- file_ptr = file_ptr->next_file)
- {
- if (file_ptr->fd == event_file_desc)
- {
- /* See if the desired events (mask) match the received
- events (ready_mask). */
-
- if (file_ptr->ready_mask & GDB_EXCEPTION)
- {
- warning ("Exception condition detected on fd %s",
- pfildes (file_ptr->fd));
- file_ptr->error = 1;
- }
- else
- file_ptr->error = 0;
- mask = file_ptr->ready_mask & file_ptr->mask;
-
- /* Clear the received events for next time around. */
- file_ptr->ready_mask = 0;
-
- /* If there was a match, then call the handler. */
- if (mask != 0)
- {
- if ((*file_ptr->proc) (file_ptr->error,
- file_ptr->client_data) < 0)
- return -1;
- }
- break;
- }
- }
-
- return 0;
-}
-
-/* Create a file event, to be enqueued in the event queue for
- processing. The procedure associated to this event is always
- handle_file_event, which will in turn invoke the one that was
- associated to FD when it was registered with the event loop. */
-
-static gdb_event *
-create_file_event (gdb_fildes_t fd)
-{
- gdb_event *file_event_ptr;
-
- file_event_ptr = XNEW (gdb_event);
- file_event_ptr->proc = handle_file_event;
- file_event_ptr->fd = fd;
-
- return file_event_ptr;
-}
-
-/* Called by do_one_event to wait for new events on the monitored file
- descriptors. Queue file events as they are detected by the poll.
- If there are no events, this function will block in the call to
- select. Return -1 if there are no files descriptors to monitor,
- otherwise return 0. */
-
-static int
-wait_for_event (void)
-{
- file_handler *file_ptr;
- int num_found = 0;
-
- /* Make sure all output is done before getting another event. */
- fflush (stdout);
- fflush (stderr);
-
- if (gdb_notifier.num_fds == 0)
- return -1;
-
- gdb_notifier.ready_masks[0] = gdb_notifier.check_masks[0];
- gdb_notifier.ready_masks[1] = gdb_notifier.check_masks[1];
- gdb_notifier.ready_masks[2] = gdb_notifier.check_masks[2];
- num_found = select (gdb_notifier.num_fds,
- &gdb_notifier.ready_masks[0],
- &gdb_notifier.ready_masks[1],
- &gdb_notifier.ready_masks[2],
- NULL);
-
- /* Clear the masks after an error from select. */
- if (num_found == -1)
- {
- FD_ZERO (&gdb_notifier.ready_masks[0]);
- FD_ZERO (&gdb_notifier.ready_masks[1]);
- FD_ZERO (&gdb_notifier.ready_masks[2]);
-#ifdef EINTR
- /* Dont print anything if we got a signal, let gdb handle
- it. */
- if (errno != EINTR)
- perror_with_name ("select");
-#endif
- }
-
- /* Enqueue all detected file events. */
-
- for (file_ptr = gdb_notifier.first_file_handler;
- file_ptr != NULL && num_found > 0;
- file_ptr = file_ptr->next_file)
- {
- int mask = 0;
-
- if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[0]))
- mask |= GDB_READABLE;
- if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[1]))
- mask |= GDB_WRITABLE;
- if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[2]))
- mask |= GDB_EXCEPTION;
-
- if (!mask)
- continue;
- else
- num_found--;
-
- /* Enqueue an event only if this is still a new event for this
- fd. */
-
- if (file_ptr->ready_mask == 0)
- {
- gdb_event *file_event_ptr = create_file_event (file_ptr->fd);
-
- event_queue.emplace (file_event_ptr);
- }
- file_ptr->ready_mask = mask;
- }
-
- return 0;
-}
-
-/* Start up the event loop. This is the entry point to the event
- loop. */
-
-void
-start_event_loop (void)
-{
- /* Loop until there is nothing to do. This is the entry point to
- the event loop engine. If nothing is ready at this time, wait
- for something to happen (via wait_for_event), then process it.
- Return when there are no longer event sources to wait for. */
-
- while (1)
- {
- /* Any events already waiting in the queue? */
- int res = process_event ();
-
- /* Did the event handler want the event loop to stop? */
- if (res == -1)
- return;
-
- if (res)
- continue;
-
- /* Process any queued callbacks before we go to sleep. */
- res = process_callback ();
-
- /* Did the callback want the event loop to stop? */
- if (res == -1)
- return;
-
- if (res)
- continue;
-
- /* Wait for a new event. If wait_for_event returns -1, we
- should get out because this means that there are no event
- sources left. This will make the event loop stop, and the
- application exit. */
-
- if (wait_for_event () < 0)
- return;
- }
-
- /* We are done with the event loop. There are no more event sources
- to listen to. So we exit gdbserver. */
-}
diff --git a/gdbserver/event-loop.h b/gdbserver/event-loop.h
deleted file mode 100644
index a49173e..0000000
--- a/gdbserver/event-loop.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Event loop machinery for the remote server for GDB.
- Copyright (C) 1993-2020 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 GDBSERVER_EVENT_LOOP_H
-#define GDBSERVER_EVENT_LOOP_H
-
-typedef void *gdb_client_data;
-typedef int (handler_func) (int, gdb_client_data);
-typedef int (callback_handler_func) (gdb_client_data);
-
-extern void delete_file_handler (gdb_fildes_t fd);
-extern void add_file_handler (gdb_fildes_t fd, handler_func *proc,
- gdb_client_data client_data);
-extern int append_callback_event (callback_handler_func *proc,
- gdb_client_data client_data);
-extern void delete_callback_event (int id);
-
-extern void start_event_loop (void);
-extern void initialize_event_loop (void);
-
-#endif /* GDBSERVER_EVENT_LOOP_H */
diff --git a/gdbserver/remote-utils.cc b/gdbserver/remote-utils.cc
index 1c211e2..6249691 100644
--- a/gdbserver/remote-utils.cc
+++ b/gdbserver/remote-utils.cc
@@ -144,7 +144,7 @@ enable_async_notification (int fd)
#endif
}
-static int
+static void
handle_accept_event (int err, gdb_client_data client_data)
{
struct sockaddr_storage sockaddr;
@@ -213,8 +213,6 @@ handle_accept_event (int err, gdb_client_data client_data)
until GDB as selected all-stop/non-stop, and has queried the
threads' status ('?'). */
target_async (0);
-
- return 0;
}
/* Prepare for a later connection to a remote debugger.
@@ -930,27 +928,21 @@ reset_readchar (void)
readchar_bufcnt = 0;
if (readchar_callback != NOT_SCHEDULED)
{
- delete_callback_event (readchar_callback);
+ delete_timer (readchar_callback);
readchar_callback = NOT_SCHEDULED;
}
}
/* Process remaining data in readchar_buf. */
-static int
+static void
process_remaining (void *context)
{
- int res;
-
/* This is a one-shot event. */
readchar_callback = NOT_SCHEDULED;
if (readchar_bufcnt > 0)
- res = handle_serial_event (0, NULL);
- else
- res = 0;
-
- return res;
+ handle_serial_event (0, NULL);
}
/* If there is still data in the buffer, queue another event to process it,
@@ -960,7 +952,7 @@ static void
reschedule (void)
{
if (readchar_bufcnt > 0 && readchar_callback == NOT_SCHEDULED)
- readchar_callback = append_callback_event (process_remaining, NULL);
+ readchar_callback = create_timer (0, process_remaining, NULL);
}
/* Read a packet from the remote machine, with error checking,
diff --git a/gdbserver/server.cc b/gdbserver/server.cc
index ac7a7fd..77175ff 100644
--- a/gdbserver/server.cc
+++ b/gdbserver/server.cc
@@ -83,6 +83,10 @@ bool run_once;
/* Whether to report TARGET_WAITKIND_NO_RESUMED events. */
static bool report_no_resumed;
+/* The event loop checks this to decide whether to continue accepting
+ events. */
+static bool keep_processing_events = true;
+
bool non_stop;
static struct {
@@ -3463,6 +3467,32 @@ gdbserver_show_disableable (FILE *stream)
" threads \tAll of the above\n");
}
+/* Start up the event loop. This is the entry point to the event
+ loop. */
+
+static void
+start_event_loop ()
+{
+ /* Loop until there is nothing to do. This is the entry point to
+ the event loop engine. If nothing is ready at this time, wait
+ for something to happen (via wait_for_event), then process it.
+ Return when there are no longer event sources to wait for. */
+
+ keep_processing_events = true;
+ while (keep_processing_events)
+ {
+ /* Any events already waiting in the queue? */
+ int res = gdb_do_one_event ();
+
+ /* Was there an error? */
+ if (res == -1)
+ break;
+ }
+
+ /* We are done with the event loop. There are no more event sources
+ to listen to. So we exit gdbserver. */
+}
+
static void
kill_inferior_callback (process_info *process)
{
@@ -3762,7 +3792,6 @@ captured_main (int argc, char *argv[])
initialize_async_io ();
initialize_low ();
have_job_control ();
- initialize_event_loop ();
if (target_supports_tracepoints ())
initialize_tracepoint ();
@@ -4365,7 +4394,7 @@ process_serial_event (void)
/* Event-loop callback for serial events. */
-int
+void
handle_serial_event (int err, gdb_client_data client_data)
{
if (debug_threads)
@@ -4373,13 +4402,14 @@ handle_serial_event (int err, gdb_client_data client_data)
/* Really handle it. */
if (process_serial_event () < 0)
- return -1;
+ {
+ keep_processing_events = false;
+ return;
+ }
/* Be sure to not change the selected thread behind GDB's back.
Important in the non-stop mode asynchronous protocol. */
set_desired_thread ();
-
- return 0;
}
/* Push a stop notification on the notification queue. */
@@ -4397,7 +4427,7 @@ push_stop_notification (ptid_t ptid, struct target_waitstatus *status)
/* Event-loop callback for target events. */
-int
+void
handle_target_event (int err, gdb_client_data client_data)
{
client_state &cs = get_client_state ();
@@ -4474,8 +4504,6 @@ handle_target_event (int err, gdb_client_data client_data)
/* Be sure to not change the selected thread behind GDB's back.
Important in the non-stop mode asynchronous protocol. */
set_desired_thread ();
-
- return 0;
}
/* See gdbsupport/event-loop.h. */
diff --git a/gdbserver/server.h b/gdbserver/server.h
index 5ef48b6..039082e 100644
--- a/gdbserver/server.h
+++ b/gdbserver/server.h
@@ -88,13 +88,13 @@ typedef SOCKET gdb_fildes_t;
typedef int gdb_fildes_t;
#endif
-#include "event-loop.h"
+#include "gdbsupport/event-loop.h"
/* Functions from server.c. */
extern void handle_v_requests (char *own_buf, int packet_len,
int *new_packet_len);
-extern int handle_serial_event (int err, gdb_client_data client_data);
-extern int handle_target_event (int err, gdb_client_data client_data);
+extern void handle_serial_event (int err, gdb_client_data client_data);
+extern void handle_target_event (int err, gdb_client_data client_data);
/* Get rid of the currently pending stop replies that match PTID. */
extern void discard_queued_stop_replies (ptid_t ptid);