From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16148 invoked by alias); 17 Oct 2008 20:55:32 -0000 Received: (qmail 16139 invoked by uid 22791); 17 Oct 2008 20:55:29 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 17 Oct 2008 20:54:54 +0000 Received: (qmail 12071 invoked from network); 17 Oct 2008 20:54:51 -0000 Received: from unknown (HELO orlando.local) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 17 Oct 2008 20:54:51 -0000 From: Pedro Alves To: gdb-patches@sourceware.org, Eli Zaretskii Subject: Re: generic `struct serial' interface pipe for remote non-stop Date: Fri, 17 Oct 2008 20:55:00 -0000 User-Agent: KMail/1.9.9 References: <200810170034.50863.pedro@codesourcery.com> In-Reply-To: MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_auP+I+IbFkKhrmR" Message-Id: <200810172154.50092.pedro@codesourcery.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-10/txt/msg00449.txt.bz2 --Boundary-00=_auP+I+IbFkKhrmR Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 3363 On Friday 17 October 2008 11:21:27, Eli Zaretskii wrote: > > From: Pedro Alves > Forgive me, especially if I talk out of ignorance or misunderstanding, > but isn't this a horrible design? We need to communicate to the event > loop that some event happened, and we do that by opening a pipe > between one part of GDB and another, and talk to ourselves via that > pipe? > > Can't we instead register with the event loop some callback that would > tell the loop that an event arrived? Heck, even raise-ing a signal > would be better. > Believe me or not, I had just changed to using pipes very recently ... I was using the asynchronous signal handling mechanism already in place, until I found out that it wasn't sufficient for my purposes, so I thought that reusing pipes was the most expedite way to solve this issue. I was also avoiding touching the event loop design, which is heavilly file descriptor based. Read through event-loop.c. > > For go32/djgpp or for unix hosts that don't have socketpair, I > > just bail out with ENOSYS. > > Does that mean that some feature that could have worked for DJGPP with > a different design, will now be broken by design? If so, I'd like us > to look for alternatives. > I can't honestly, seriously believe that anyone would be so masochist enough as to be doing non-stop cross-debugging from DJGPP. And, it's not like you couldn't implement in-process pipes on DJGPP, and implement a gdb_select on DJGPP too. We do this for Windows. That being said, I took a step back, and relooked at the problems I was having with async signals handlers, which is a mechanism to register a callback function in the event-loop. Notice that the currently event loop design is heavilly based on waitable file descriptors, with async signal handlers being a secondary input event source. So I came up with the attached patch to adjust it to my needs. The biggest problem the attached patch solves is: - Since async signal handlers are always checked before polling the file descriptors, I can easily starve the file descriptor based sources. E.g., if I place several threads displace stepping a breakpoint, forcing continuous remote traffic, the CLI becomes very, very unresponsive, unusable really. This is because stdin itself is registered as a monitored (via select/poll) file descriptor. To solve this, I adjusted the event loop to give equal priority to all event-sources (timers, async signal handlers, monitored file descriptors). The async signal handling was changed to instead of immediatelly calling the associated callback, it installs an event in the "ready" queue, just like the file-descriptor and timer based sources. I then make sure that I poll each of the possible event sources once (select/poll with timeout 0 too). If if no event is found ready, then, we go blocking waiting for one in select/poll. I can sucessfully debug a non-stop linux gdbserver from both a linux host and a Windows (mingw32) host with this. The remote.c changes below apply on top of the non-stop support patch I sent yesterday, and it's what I used to test, shown here so you could see what was required that change, in case you're curious about it. Do you think it is a better alternative? I can't think of a reason this wouldn't work on DJGPP. -- Pedro Alves --Boundary-00=_auP+I+IbFkKhrmR Content-Type: text/x-diff; charset="utf-8"; name="unpipes.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="unpipes.diff" Content-length: 23253 2008-10-17 Pedro Alves * event-loop.c (event_data): New. (event_handler_func): Take an event_data instead of an integer. (struct gdb_event): Replace the integer file descriptor by a generic event_data. (async_handler_ready): Delete. (create_event): New. (create_file_event): Use it. (process_event): Don't check async signal handlers here. Adjust. (gdb_do_one_event): Poll from the event sources in round-robin fashion across calls. Be sure to consult all sources before blocking. (handle_file_event): Take an event_data instead of an integer. Adjust. (gdb_wait_for_event): Add `block' argument. Handle it. (mark_async_signal_handler): Adjust. (struct signal_handler_data): New. (invoke_async_signal_handler): Rename to ... (check_async_signal_handlers): ... this. Enqueue an event instead of calling the callback here. (check_async_ready): Delete. (handle_timer_event): Adjust. --- gdb/event-loop.c | 261 ++++++++++++++++++++++++++++++++++--------------------- gdb/remote.c | 132 +++++++-------------------- 2 files changed, 201 insertions(+), 192 deletions(-) Index: src/gdb/event-loop.c =================================================================== --- src.orig/gdb/event-loop.c 2008-10-17 19:11:14.000000000 +0100 +++ src/gdb/event-loop.c 2008-10-17 20:14:41.000000000 +0100 @@ -38,25 +38,40 @@ #include "gdb_assert.h" #include "gdb_select.h" +/* Data point to pass to the event handler. */ +typedef union event_data +{ + void *ptr; + int integer; +} event_data; + typedef struct gdb_event gdb_event; -typedef void (event_handler_func) (int); +typedef void (event_handler_func) (event_data); /* Event for the GDB event system. Events are queued by calling async_queue_event and serviced later on by gdb_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 + 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. */ + ready. The procedure PROC associated with each event is dependant + of the event source. In the case of monitored file descriptors, it + 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. In the + case of async signal handlers, it is + invoke_async_signal_handler. */ struct gdb_event { - event_handler_func *proc; /* Procedure to call to service this event. */ - int fd; /* File descriptor that is ready. */ - struct gdb_event *next_event; /* Next in list of events or NULL. */ + /* Procedure to call to service this event. */ + event_handler_func *proc; + + /* Data to pass to the event handler. */ + event_data data; + + /* Next in list of events or NULL. */ + struct gdb_event *next_event; }; /* Information about each file descriptor we register with the event @@ -207,21 +222,13 @@ static struct } sighandler_list; -/* Are any of the handlers ready? Check this variable using - check_async_ready. This is used by process_event, to determine - whether or not to invoke the invoke_async_signal_handler - function. */ -static int async_handler_ready = 0; - static void create_file_handler (int fd, int mask, handler_func * proc, gdb_client_data client_data); -static void invoke_async_signal_handler (void); -static void handle_file_event (int event_file_desc); -static int gdb_wait_for_event (void); -static int check_async_ready (void); +static void check_async_signal_handlers (); +static void handle_file_event (event_data data); +static int gdb_wait_for_event (int); static void async_queue_event (gdb_event * event_ptr, queue_position position); static gdb_event *create_file_event (int fd); static int process_event (void); -static void handle_timer_event (int dummy); static void poll_timers (void); @@ -260,6 +267,22 @@ async_queue_event (gdb_event * event_ptr } } +/* Create a generic event, to be enqueued in the event queue for + processing. PROC is the procedure associated to the event. DATA + is passed to PROC uppon PROC invocation. */ + +static gdb_event * +create_event (event_handler_func proc, event_data data) +{ + gdb_event *event; + + event = xmalloc (sizeof (*event)); + event->proc = proc; + event->data = data; + + return event; +} + /* 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 @@ -267,12 +290,10 @@ async_queue_event (gdb_event * event_ptr static gdb_event * create_file_event (int fd) { - gdb_event *file_event_ptr; + event_data data; - file_event_ptr = (gdb_event *) xmalloc (sizeof (gdb_event)); - file_event_ptr->proc = handle_file_event; - file_event_ptr->fd = fd; - return (file_event_ptr); + data.integer = fd; + return create_event (handle_file_event, data); } /* Process one event. @@ -289,17 +310,7 @@ process_event (void) { gdb_event *event_ptr, *prev_ptr; event_handler_func *proc; - int fd; - - /* First let's see if there are any asynchronous event handlers that - are ready. These would be the result of invoking any of the - signal handlers. */ - - if (check_async_ready ()) - { - invoke_async_signal_handler (); - return 1; - } + event_data data; /* Look in the event queue to find an event that is ready to be processed. */ @@ -310,7 +321,7 @@ process_event (void) /* Call the handler for the event. */ proc = event_ptr->proc; - fd = event_ptr->fd; + data = event_ptr->data; /* Let's get rid of the event from the event queue. We need to do this now because while processing the event, the proc @@ -338,7 +349,7 @@ process_event (void) xfree (event_ptr); /* Now call the procedure associated with the event. */ - (*proc) (fd); + (*proc) (data); return 1; } @@ -355,33 +366,61 @@ process_event (void) int gdb_do_one_event (void *data) { - /* Any events already waiting in the queue? */ + static int event_source_head = 0; + static const int number_of_sources = 3; + int current = 0; + + /* Any events already waiting in the queue? */ if (process_event ()) + return 1; + + /* To level the fairness across event sources, we poll them in a + round-robin fashion. */ + for (current = 0; current < number_of_sources; current++) { - return 1; + switch (event_source_head) + { + case 0: + /* Are any timers that are ready? If so, put an event on the + queue. */ + poll_timers (); + break; + case 1: + /* Are there events already waiting to be collected on the + monitored file descriptors? */ + gdb_wait_for_event (0); + break; + case 2: + /* Are there any asynchronous event handlers ready? These + would be the result of invoking any of the signal + handlers. */ + check_async_signal_handlers (); + break; + } + + event_source_head++; + if (event_source_head == number_of_sources) + event_source_head = 0; } - /* Are any timers that are ready? If so, put an event on the queue. */ - poll_timers (); + /* Handle any new events collected. */ + if (process_event ()) + return 1; - /* Wait for a new event. If gdb_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. */ + /* Block waiting for a new event. If gdb_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 (gdb_wait_for_event () < 0) - { - return -1; - } + if (gdb_wait_for_event (1) < 0) + return -1; - /* Handle any new events occurred while waiting. */ + /* Handle any new events occurred while waiting. */ if (process_event ()) - { - return 1; - } + return 1; - /* If gdb_wait_for_event has returned 1, it means that one - event has been handled. We break out of the loop. */ + /* If gdb_wait_for_event has returned 1, it means that one event has + been handled. We break out of the loop. */ return 1; } @@ -659,7 +698,7 @@ delete_file_handler (int fd) through event_ptr->proc. EVENT_FILE_DESC is file descriptor of the event in the front of the event queue. */ static void -handle_file_event (int event_file_desc) +handle_file_event (event_data data) { file_handler *file_ptr; int mask; @@ -667,6 +706,7 @@ handle_file_event (int event_file_desc) int error_mask; int error_mask_returned; #endif + int event_file_desc = data.integer; /* Search the file handler list to find one that matches the fd in the event. */ @@ -735,15 +775,13 @@ handle_file_event (int event_file_desc) } } -/* Called by gdb_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 poll. - Return -1 if there are no files descriptors to monitor, - otherwise return 0. */ +/* Called by gdb_do_one_event to wait for new events on the monitored + file descriptors. Queue file events as they are detected by the + poll. If BLOCK and if there are no events, this function will + block in the call to poll. Return -1 if there are no files + descriptors to monitor, otherwise return 0. */ static int -gdb_wait_for_event (void) +gdb_wait_for_event (int block) { file_handler *file_ptr; gdb_event *file_event_ptr; @@ -760,13 +798,18 @@ gdb_wait_for_event (void) if (use_poll) { #ifdef HAVE_POLL - num_found = - poll (gdb_notifier.poll_fds, - (unsigned long) gdb_notifier.num_fds, - gdb_notifier.timeout_valid ? gdb_notifier.poll_timeout : -1); + int timeout; + + if (block) + timeout = gdb_notifier.timeout_valid ? gdb_notifier.poll_timeout : -1; + else + timeout = 0; + + num_found = poll (gdb_notifier.poll_fds, + (unsigned long) gdb_notifier.num_fds, timeout); /* Don't print anything if we get out of poll because of a - signal. */ + signal. */ if (num_found == -1 && errno != EINTR) perror_with_name (("poll")); #else @@ -776,6 +819,18 @@ gdb_wait_for_event (void) } else { + struct timeval select_timeout; + + struct timeval *timeout_p; + if (block) + timeout_p = gdb_notifier.timeout_valid + ? &gdb_notifier.select_timeout : NULL; + else + { + memset (&select_timeout, 0, sizeof (select_timeout)); + timeout_p = &select_timeout; + } + 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]; @@ -783,8 +838,7 @@ gdb_wait_for_event (void) &gdb_notifier.ready_masks[0], &gdb_notifier.ready_masks[1], &gdb_notifier.ready_masks[2], - gdb_notifier.timeout_valid - ? &gdb_notifier.select_timeout : NULL); + timeout_p); /* Clear the masks after an error from select. */ if (num_found == -1) @@ -792,7 +846,9 @@ gdb_wait_for_event (void) FD_ZERO (&gdb_notifier.ready_masks[0]); FD_ZERO (&gdb_notifier.ready_masks[1]); FD_ZERO (&gdb_notifier.ready_masks[2]); - /* Dont print anything is we got a signal, let gdb handle it. */ + + /* Dont print anything if we got a signal, let gdb handle + it. */ if (errno != EINTR) perror_with_name (("select")); } @@ -912,20 +968,31 @@ void mark_async_signal_handler (async_signal_handler * async_handler_ptr) { ((async_signal_handler *) async_handler_ptr)->ready = 1; - async_handler_ready = 1; } -/* Call all the handlers that are ready. */ +struct signal_handler_data +{ + sig_handler_func* proc; + gdb_client_data client_data; +}; + static void -invoke_async_signal_handler (void) +invoke_async_signal_handler (event_data data) { - async_signal_handler *async_handler_ptr; + struct signal_handler_data *hdata = data.ptr; + (*hdata->proc) (hdata->client_data); - if (async_handler_ready == 0) - return; - async_handler_ready = 0; + xfree (hdata); +} - /* Invoke ready handlers. */ +/* Check if any signal handlers are ready. */ +static void +check_async_signal_handlers (void) +{ + async_signal_handler *async_handler_ptr; + struct signal_handler_data *hdata; + struct gdb_event *event_ptr; + event_data data; while (1) { @@ -938,11 +1005,20 @@ invoke_async_signal_handler (void) } if (async_handler_ptr == NULL) break; + async_handler_ptr->ready = 0; - (*async_handler_ptr->proc) (async_handler_ptr->client_data); - } - return; + hdata = xmalloc (sizeof (*hdata)); + + hdata->proc = async_handler_ptr->proc; + hdata->client_data = async_handler_ptr->client_data; + + data.ptr = hdata; + + event_ptr = create_event (invoke_async_signal_handler, data); + async_queue_event (event_ptr, TAIL); + break; + } } /* Delete an asynchronous handler (ASYNC_HANDLER_PTR). @@ -971,13 +1047,6 @@ delete_async_signal_handler (async_signa (*async_handler_ptr) = NULL; } -/* Is it necessary to call invoke_async_signal_handler? */ -static int -check_async_ready (void) -{ - return async_handler_ready; -} - /* Create a timer that will expire in MILLISECONDS from now. When the timer is ready, PROC will be executed. At creation, the timer is aded to the timers queue. This queue is kept sorted in order of @@ -1080,11 +1149,11 @@ delete_timer (int id) } /* When a timer event is put on the event queue, it will be handled by - this function. Just call the assiciated procedure and delete the - timer event from the event queue. Repeat this for each timer that - has expired. */ + this function. Just call the associated procedure and delete the + timer event from the event queue. Repeat this for each timer that + has expired. */ static void -handle_timer_event (int dummy) +handle_timer_event (event_data dummy) { struct timeval time_now; struct gdb_timer *timer_ptr, *saved_timer; @@ -1150,7 +1219,7 @@ poll_timers (void) { event_ptr = (gdb_event *) xmalloc (sizeof (gdb_event)); event_ptr->proc = handle_timer_event; - event_ptr->fd = timer_list.first_timer->timer_id; + event_ptr->data.integer = timer_list.first_timer->timer_id; async_queue_event (event_ptr, TAIL); } Index: src/gdb/remote.c =================================================================== --- src.orig/gdb/remote.c 2008-10-17 20:14:40.000000000 +0100 +++ src/gdb/remote.c 2008-10-17 20:27:10.000000000 +0100 @@ -229,10 +229,8 @@ static void remote_get_pending_stop_repl static void discard_pending_stop_replies (int pid); static int peek_stop_reply (ptid_t ptid); -static void remote_async_inferior_event_handler (struct serial *scb, - void *context); -static void remote_async_get_pending_events_handler (struct serial *scb, - void *context); +static void remote_async_inferior_event_handler (gdb_client_data); +static void remote_async_get_pending_events_handler (gdb_client_data); /* The non-stop remote protocol provisions for one pending stop reply. This is where we keep it until it is acknowledged. */ @@ -1101,77 +1099,17 @@ static struct async_signal_handler *sigi static struct async_signal_handler *sigint_remote_token; -/* Pipes for use by the asynchronous event processing used in non-stop - mode. */ - -/* The read handle of this pipe is registered as the event source of +/* Asynchronous signal handle registered as event loop source for when we have pending events ready to be passed to the core. */ -static struct serial *remote_inferior_event_pipe[2]; - -/* The read handle of this pipe is registered as the event source of - when the remote sent as a %Stop notification. The registered - callback will do a vStopped sequence to pull the rest of the events - out of the remote side into our event queue. */ - -static struct serial *remote_get_pending_events_pipe[2]; +static struct async_signal_handler *remote_async_inferior_event_token; -static void -make_event_pipes (void) -{ - /* Create event pipes and register them in the event loop. */ - if (serial_pipe (remote_inferior_event_pipe) == -1 - || serial_pipe (remote_get_pending_events_pipe) == -1) - perror_with_name (_("Creating the non-stop mode event files failed")); +/* Asynchronous signal handle registered as event loop source for when + the remote sent us a %Stop notification. The registered callback + will do a vStopped sequence to pull the rest of the events out of + the remote side into our event queue. */ - /* Register the read handles in the event loop. */ - serial_async (remote_inferior_event_pipe[0], - remote_async_inferior_event_handler, NULL); - serial_async (remote_get_pending_events_pipe[0], - remote_async_get_pending_events_handler, NULL); -} - -/* Destroy a pipe previously created by MAKE_EVENT_PIPE and remove it - from the event loop. */ - -static void -close_event_pipe (struct serial *mypipe[2]) -{ - if (mypipe[0]) - { - serial_close (mypipe[0]); - serial_close (mypipe[1]); - mypipe[0] = NULL; - mypipe[1] = NULL; - } -} - -/* Flush the read end of the pipe. */ - -static void -event_file_flush (struct serial *mypipe[2]) -{ - int ch; - - serial_flush_input (mypipe[0]); - - do - { - ch = serial_readchar (mypipe[0], 0); - } - while (ch >= 0); -} - -/* Put something in the pipe, so the event loop wakes up. */ - -static void -event_file_mark (struct serial *mypipe[2]) -{ - event_file_flush (mypipe); - - if (serial_write (mypipe[1], "+", 1)) - perror_with_name (_("event_file_mark: write failed")); -} +static struct async_signal_handler *remote_async_get_pending_events_token; static ptid_t magic_null_ptid; @@ -2370,8 +2308,10 @@ remote_close (int quitting) /* We're no longer interested in any of these events. */ discard_pending_stop_replies (-1); - close_event_pipe (remote_inferior_event_pipe); - close_event_pipe (remote_get_pending_events_pipe); + if (remote_async_inferior_event_token) + delete_async_signal_handler (&remote_async_inferior_event_token); + if (remote_async_get_pending_events_token) + delete_async_signal_handler (&remote_async_get_pending_events_token); generic_mourn_inferior (); } @@ -2620,9 +2560,6 @@ remote_start_remote (struct ui_out *uiou if (!rs->non_stop_aware) error (_("Non-stop mode requested, but remote does not support non-stop")); - /* Make the event pipes and register them in the event loop. */ - make_event_pipes (); - putpkt ("QNonStop:1"); getpkt (&rs->buf, &rs->buf_size, 0); @@ -3220,6 +3157,14 @@ remote_open_1 (char *name, int from_tty, /* Assume that the target is running, unless we learn otherwise. */ target_mark_running (target); + /* Register extra event sources in the event loop. */ + remote_async_inferior_event_token + = create_async_signal_handler (remote_async_inferior_event_handler, + NULL); + remote_async_get_pending_events_token + = create_async_signal_handler (remote_async_get_pending_events_handler, + NULL); + /* Reset the target state; these things will be queried either by remote_query_supported or as they are needed. */ init_all_packet_configs (); @@ -4174,7 +4119,7 @@ queued_stop_reply (ptid_t ptid) if (stop_reply_queue) /* There's still at least an event left. */ - event_file_mark (remote_inferior_event_pipe); + mark_async_signal_handler (remote_async_inferior_event_token); return it; } @@ -4200,7 +4145,7 @@ push_stop_reply (struct stop_reply *new_ else stop_reply_queue = new_event; - event_file_mark (remote_inferior_event_pipe); + mark_async_signal_handler (remote_async_inferior_event_token); } /* Returns true if we have a stop reply for PTID. */ @@ -4433,21 +4378,21 @@ Packet: '%s'\n"), query. To solve this, whenever we parse a %Stop notification sucessfully, - we mark the REMOTE_GET_PENDING_EVENTS_PIPE, and carry on doing + we mark the REMOTE_ASYN_GET_PENDING_EVENTS_TOKEN, and carry on doing whatever we were doing: 2.1) --> Hg 1 2.2) <-- OK 2.3) --> g 2.4) <-- %Stop - + 2.5) <-- (registers reply to step #2.3) Eventualy after step #2.5, we return to the event loop, which - selects/polls on the REMOTE_GET_PENDING_EVENTS_PIPE read end. Since - there's something there to read, GDB calls the pipe's associated - callback --- the function below. At this point, we're always safe - to start a vStopped sequence. : + notices there's an event on the + REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN signal and calls the + associated callback --- the function below. At this point, we're + always safe to start a vStopped sequence. : 2.6) --> vStopped 2.7) <-- T05 thread:2 @@ -4768,13 +4713,10 @@ remote_wait (ptid_t ptid, struct target_ if (target_can_async_p ()) { - /* If there are no events left in the queue, we can stop coming - back. If there's something else there, then please return - here. */ - if (!stop_reply_queue) - event_file_flush (remote_inferior_event_pipe); - else - event_file_mark (remote_inferior_event_pipe); + /* If there are are events left in the queue tell the event loop + to return here. */ + if (stop_reply_queue) + mark_async_signal_handler (remote_async_inferior_event_token); } return event_ptid; @@ -5686,7 +5628,7 @@ handle_notification (char *buf, size_t l /* Notify the event loop there's a stop reply to acknowledge and that there may be more events to fetch. */ - event_file_mark (remote_get_pending_events_pipe); + mark_async_signal_handler (remote_async_get_pending_events_token); } } else @@ -8694,16 +8636,14 @@ remote_async_serial_handler (struct seri } static void -remote_async_inferior_event_handler (struct serial *scb, void *context) +remote_async_inferior_event_handler (gdb_client_data data) { inferior_event_handler (INF_REG_EVENT, NULL); } static void -remote_async_get_pending_events_handler (struct serial *scb, void *context) +remote_async_get_pending_events_handler (gdb_client_data data) { - event_file_flush (remote_get_pending_events_pipe); - remote_get_pending_stop_replies (); } --Boundary-00=_auP+I+IbFkKhrmR--