X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fremote-notif.c;h=2680618b3fa7a7a615eba4e9f58ae7597caa32e3;hb=739b5c9c778dee9e2f54d864f83a81ecb0639535;hp=eee09a93c2252201afb0451ea6b670969676d104;hpb=c9b6281a3613cf8ac8f5d2e05c4c73e73f8d5fe7;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/remote-notif.c b/gdb/remote-notif.c index eee09a93c2..2680618b3f 100644 --- a/gdb/remote-notif.c +++ b/gdb/remote-notif.c @@ -1,6 +1,6 @@ /* Remote notification in GDB protocol - Copyright (C) 1988-2012 Free Software Foundation, Inc. + Copyright (C) 1988-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -34,15 +34,14 @@ #include "defs.h" #include "remote.h" #include "remote-notif.h" -#include "observer.h" +#include "observable.h" #include "event-loop.h" #include "target.h" #include "inferior.h" +#include "infrun.h" #include "gdbcmd.h" -#include - -unsigned int notif_debug = 0; +int notif_debug = 0; /* Supported clients of notifications. */ @@ -51,124 +50,93 @@ static struct notif_client *notifs[] = ¬if_client_stop, }; -static void do_notif_event_xfree (void *arg); +gdb_static_assert (ARRAY_SIZE (notifs) == REMOTE_NOTIF_LAST); /* Parse the BUF for the expected notification NC, and send packet to acknowledge. */ void -remote_notif_ack (struct notif_client *nc, char *buf) +remote_notif_ack (remote_target *remote, + struct notif_client *nc, const char *buf) { - struct notif_event *event = nc->alloc_event (); - struct cleanup *old_chain - = make_cleanup (do_notif_event_xfree, event); + notif_event_up event = nc->alloc_event (); if (notif_debug) fprintf_unfiltered (gdb_stdlog, "notif: ack '%s'\n", nc->ack_command); - nc->parse (nc, buf, event); - nc->ack (nc, buf, event); - - discard_cleanups (old_chain); + nc->parse (remote, nc, buf, event.get ()); + nc->ack (remote, nc, buf, event.release ()); } /* Parse the BUF for the expected notification NC. */ struct notif_event * -remote_notif_parse (struct notif_client *nc, char *buf) +remote_notif_parse (remote_target *remote, + struct notif_client *nc, const char *buf) { - struct notif_event *event = nc->alloc_event (); - struct cleanup *old_chain - = make_cleanup (do_notif_event_xfree, event); + notif_event_up event = nc->alloc_event (); if (notif_debug) fprintf_unfiltered (gdb_stdlog, "notif: parse '%s'\n", nc->name); - nc->parse (nc, buf, event); + nc->parse (remote, nc, buf, event.get ()); - discard_cleanups (old_chain); - return event; + return event.release (); } -DECLARE_QUEUE_P (notif_client_p); -DEFINE_QUEUE_P (notif_client_p); - -static QUEUE(notif_client_p) *notif_queue; - -/* Process notifications one by one. EXCEPT is not expected in - the queue. */ +/* Process notifications in STATE's notification queue one by one. + EXCEPT is not expected in the queue. */ void -remote_notif_process (struct notif_client *except) +remote_notif_process (struct remote_notif_state *state, + struct notif_client *except) { - while (!QUEUE_is_empty (notif_client_p, notif_queue)) + while (!state->notif_queue.empty ()) { - struct notif_client *nc = QUEUE_deque (notif_client_p, - notif_queue); + struct notif_client *nc = state->notif_queue.front (); + state->notif_queue.pop_front (); gdb_assert (nc != except); - if (nc->can_get_pending_events (nc)) - remote_notif_get_pending_events (nc); + if (nc->can_get_pending_events (state->remote, nc)) + remote_notif_get_pending_events (state->remote, nc); } } static void remote_async_get_pending_events_handler (gdb_client_data data) { - gdb_assert (non_stop); - remote_notif_process (NULL); -} - -/* Asynchronous signal handle registered as event loop source for when - the remote sent us a notification. The registered callback - will do a ACK sequence to pull the rest of the events out of - the remote side into our event queue. */ - -static struct async_event_handler *remote_async_get_pending_events_token; - -/* Register async_event_handler for notification. */ - -void -remote_notif_register_async_event_handler (void) -{ - remote_async_get_pending_events_token - = create_async_event_handler (remote_async_get_pending_events_handler, - NULL); -} - -/* Unregister async_event_handler for notification. */ - -void -remote_notif_unregister_async_event_handler (void) -{ - if (remote_async_get_pending_events_token) - delete_async_event_handler (&remote_async_get_pending_events_token); + gdb_assert (target_is_non_stop_p ()); + remote_notif_process ((struct remote_notif_state *) data, NULL); } -/* Remote notification handler. */ +/* Remote notification handler. Parse BUF, queue notification and + update STATE. */ void -handle_notification (char *buf) +handle_notification (struct remote_notif_state *state, const char *buf) { - struct notif_client *nc = NULL; - int i; + struct notif_client *nc; + size_t i; for (i = 0; i < ARRAY_SIZE (notifs); i++) { - nc = notifs[i]; - if (strncmp (buf, nc->name, strlen (nc->name)) == 0 - && buf[strlen (nc->name)] == ':') + const char *name = notifs[i]->name; + + if (startswith (buf, name) + && buf[strlen (name)] == ':') break; } /* We ignore notifications we don't recognize, for compatibility with newer stubs. */ - if (nc == NULL) + if (i == ARRAY_SIZE (notifs)) return; - if (nc->pending_event) + nc = notifs[i]; + + if (state->pending_event[nc->id] != NULL) { /* We've already parsed the in-flight reply, but the stub for some reason thought we didn't, possibly due to timeout on its side. @@ -180,16 +148,16 @@ handle_notification (char *buf) else { struct notif_event *event - = remote_notif_parse (nc, buf + strlen (nc->name) + 1); + = remote_notif_parse (state->remote, nc, buf + strlen (nc->name) + 1); /* Be careful to only set it after parsing, since an error may be thrown then. */ - nc->pending_event = event; + state->pending_event[nc->id] = event; /* Notify the event loop there's a stop reply to acknowledge and that there may be more events to fetch. */ - QUEUE_enque (notif_client_p, notif_queue, nc); - if (non_stop) + state->notif_queue.push_back (nc); + if (target_is_non_stop_p ()) { /* In non-stop, We mark REMOTE_ASYNC_GET_PENDING_EVENTS_TOKEN in order to go on what we were doing and postpone @@ -227,7 +195,7 @@ handle_notification (char *buf) 2.3) <-- T05 thread:2 These pending notifications can be processed later. */ - mark_async_event_handler (remote_async_get_pending_events_token); + mark_async_event_handler (state->get_pending_events_token); } if (notif_debug) @@ -237,38 +205,41 @@ handle_notification (char *buf) } } -/* Cleanup wrapper. */ +/* Return an allocated remote_notif_state. */ -static void -do_notif_event_xfree (void *arg) +struct remote_notif_state * +remote_notif_state_allocate (remote_target *remote) { - struct notif_event *event = arg; + struct remote_notif_state *notif_state = new struct remote_notif_state; - if (event && event->dtr) - event->dtr (event); + notif_state->remote = remote; - xfree (event); + /* Register async_event_handler for notification. */ + + notif_state->get_pending_events_token + = create_async_event_handler (remote_async_get_pending_events_handler, + notif_state); + + return notif_state; } -static void -notif_xfree (struct notif_client *notif) +/* Free STATE and its fields. */ + +remote_notif_state::~remote_notif_state () { - if (notif->pending_event != NULL - && notif->pending_event->dtr != NULL) - notif->pending_event->dtr (notif->pending_event); + int i; - xfree (notif->pending_event); - xfree (notif); -} + /* Unregister async_event_handler for notification. */ + if (get_pending_events_token != NULL) + delete_async_event_handler (&get_pending_events_token); -/* -Wmissing-prototypes */ -extern initialize_file_ftype _initialize_notif; + for (i = 0; i < REMOTE_NOTIF_LAST; i++) + delete pending_event[i]; +} void _initialize_notif (void) { - notif_queue = QUEUE_alloc (notif_client_p, notif_xfree); - add_setshow_boolean_cmd ("notification", no_class, ¬if_debug, _("\ Set debugging of async remote notification."), _("\