Use std::list for event notifications in gdbserver
authorTom Tromey <tom@tromey.com>
Sun, 7 Apr 2019 22:17:40 +0000 (16:17 -0600)
committerTom Tromey <tom@tromey.com>
Fri, 19 Apr 2019 20:29:32 +0000 (14:29 -0600)
This changes gdbserver to use std::list rather than common/queue.h for
event notifications.

gdb/gdbserver/ChangeLog
2019-04-19  Tom Tromey  <tom@tromey.com>

* server.c (struct vstop_notif): Derive from notif_event.
<base>: Remove.
(queue_stop_reply): Update.
(remove_all_on_match_ptid): Change type.  Rewrite.
(discard_queued_stop_replies): Rewrite.
(in_queued_stop_replies_ptid): Change type.
(in_queued_stop_replies): Rewrite.
(notif_stop): Update.
(queue_stop_reply_callback): Update.
(captured_main): Don't call initialize_notif.
(push_stop_notification): Update.
* notif.c (notif_write_event, handle_notif_ack)
(notif_event_enque, notif_push): Update.
(notif_event_xfree, initialize_notif): Remove.
* notif.h (struct notif_event): Include <list>, not
"common/queue.h".
(struct notif_server) <queue>: Now a std::list.
(notif_event_p): Remove typedef.
(initialize_notif): Don't declare.
(struct notif_event): Add virtual destructor.

gdb/gdbserver/ChangeLog
gdb/gdbserver/notif.c
gdb/gdbserver/notif.h
gdb/gdbserver/server.c

index f8f600e46d271444ba9f97128da09f21ba92e13b..2985281518171c655a706c3469725dd8f868df7e 100644 (file)
@@ -1,3 +1,26 @@
+2019-04-19  Tom Tromey  <tom@tromey.com>
+
+       * server.c (struct vstop_notif): Derive from notif_event.
+       <base>: Remove.
+       (queue_stop_reply): Update.
+       (remove_all_on_match_ptid): Change type.  Rewrite.
+       (discard_queued_stop_replies): Rewrite.
+       (in_queued_stop_replies_ptid): Change type.
+       (in_queued_stop_replies): Rewrite.
+       (notif_stop): Update.
+       (queue_stop_reply_callback): Update.
+       (captured_main): Don't call initialize_notif.
+       (push_stop_notification): Update.
+       * notif.c (notif_write_event, handle_notif_ack)
+       (notif_event_enque, notif_push): Update.
+       (notif_event_xfree, initialize_notif): Remove.
+       * notif.h (struct notif_event): Include <list>, not
+       "common/queue.h".
+       (struct notif_server) <queue>: Now a std::list.
+       (notif_event_p): Remove typedef.
+       (initialize_notif): Don't declare.
+       (struct notif_event): Add virtual destructor.
+
 2019-04-17  Alan Hayward  <alan.hayward@arm.com>
 
        * ax.c (ax_vdebug): Call debug_printf.
index d581ccc1c0cfd7bdefa366be02b70e46a452fcec..0b526eda503e3f4dc45da2f2ed7be2e2a09aac32 100644 (file)
@@ -61,10 +61,9 @@ static struct notif_server *notifs[] =
 void
 notif_write_event (struct notif_server *notif, char *own_buf)
 {
-  if (!QUEUE_is_empty (notif_event_p, notif->queue))
+  if (!notif->queue.empty ())
     {
-      struct notif_event *event
-       = QUEUE_peek (notif_event_p, notif->queue);
+      struct notif_event *event = notif->queue.front ();
 
       notif->write (event, own_buf);
     }
@@ -98,16 +97,16 @@ handle_notif_ack (char *own_buf, int packet_len)
 
   /* If we're waiting for GDB to acknowledge a pending event,
      consider that done.  */
-  if (!QUEUE_is_empty (notif_event_p, np->queue))
+  if (!np->queue.empty ())
     {
-      struct notif_event *head
-       = QUEUE_deque (notif_event_p, np->queue);
+      struct notif_event *head = np->queue.front ();
+      np->queue.pop_front ();
 
       if (remote_debug)
        debug_printf ("%s: acking %d\n", np->ack_name,
-                     QUEUE_length (notif_event_p, np->queue));
+                     (int) np->queue.size ());
 
-      xfree (head);
+      delete head;
     }
 
   notif_write_event (np, own_buf);
@@ -121,11 +120,11 @@ void
 notif_event_enque (struct notif_server *notif,
                   struct notif_event *event)
 {
-  QUEUE_enque (notif_event_p, notif->queue, event);
+  notif->queue.push_back (event);
 
   if (remote_debug)
     debug_printf ("pending events: %s %d\n", notif->notif_name,
-                 QUEUE_length (notif_event_p, notif->queue));
+                 (int) notif->queue.size ());
 
 }
 
@@ -134,7 +133,7 @@ notif_event_enque (struct notif_server *notif,
 void
 notif_push (struct notif_server *np, struct notif_event *new_event)
 {
-  int is_first_event = QUEUE_is_empty (notif_event_p, np->queue);
+  bool is_first_event = np->queue.empty ();
 
   /* Something interesting.  Tell GDB about it.  */
   notif_event_enque (np, new_event);
@@ -153,19 +152,3 @@ notif_push (struct notif_server *np, struct notif_event *new_event)
       putpkt_notif (buf);
     }
 }
-
-static void
-notif_event_xfree (struct notif_event *event)
-{
-  xfree (event);
-}
-
-void
-initialize_notif (void)
-{
-  int i = 0;
-
-  for (i = 0; i < ARRAY_SIZE (notifs); i++)
-    notifs[i]->queue
-      = QUEUE_alloc (notif_event_p, notif_event_xfree);
-}
index 7d0767935bcf2cd8663c86a785b463078082c61d..c0525126fdc8703c83a63ff66fa3ce25d7333f61 100644 (file)
 #define GDBSERVER_NOTIF_H
 
 #include "target.h"
-#include "common/queue.h"
+#include <list>
 
 /* Structure holding information related to a single event.  We
    keep a queue of these to push to GDB.  It can be extended if
    the event of given notification contains more information.  */
 
-typedef struct notif_event
+struct notif_event
 {
-  /* C requires that a struct or union has at least one member.  */
-  char dummy;
-} *notif_event_p;
+  virtual ~notif_event ()
+  {
+  }
 
-DECLARE_QUEUE_P (notif_event_p);
+  /* No payload needed.  */
+};
 
 /* A type notification to GDB.  An object of 'struct notif_server'
    represents a type of notification.  */
@@ -49,7 +50,7 @@ typedef struct notif_server
   /* A queue of events to GDB.  A new notif_event can be enque'ed
      into QUEUE at any appropriate time, and the notif_reply is
      deque'ed only when the ack from GDB arrives.  */
-  QUEUE (notif_event_p) *queue;
+  std::list<notif_event *> queue;
 
   /* Write event EVENT to OWN_BUF.  */
   void (*write) (struct notif_event *event, char *own_buf);
@@ -64,6 +65,4 @@ void notif_push (struct notif_server *np, struct notif_event *event);
 void notif_event_enque (struct notif_server *notif,
                        struct notif_event *event);
 
-void initialize_notif (void);
-
 #endif /* GDBSERVER_NOTIF_H */
index 36510ad1b2f1af84f3c67f6b65458aba3baeaf1f..fae5b2433cf0a43eba5cbb3736da2807d69828c5 100644 (file)
@@ -140,10 +140,8 @@ static unsigned char *mem_buf;
    relative to a single stop reply.  We keep a queue of these to
    push to GDB in non-stop mode.  */
 
-struct vstop_notif
+struct vstop_notif : public notif_event
 {
-  struct notif_event base;
-
   /* Thread or process that got the event.  */
   ptid_t ptid;
 
@@ -155,8 +153,6 @@ struct vstop_notif
    btrace configuration.  */
 static struct btrace_config current_btrace_conf;
 
-DEFINE_QUEUE_P (notif_event_p);
-
 /* The client remote protocol state. */
 
 static client_state g_client_state;
@@ -174,32 +170,20 @@ get_client_state ()
 static void
 queue_stop_reply (ptid_t ptid, struct target_waitstatus *status)
 {
-  struct vstop_notif *new_notif = XNEW (struct vstop_notif);
+  struct vstop_notif *new_notif = new struct vstop_notif;
 
   new_notif->ptid = ptid;
   new_notif->status = *status;
 
-  notif_event_enque (&notif_stop, (struct notif_event *) new_notif);
+  notif_event_enque (&notif_stop, new_notif);
 }
 
-static int
-remove_all_on_match_ptid (QUEUE (notif_event_p) *q,
-                         QUEUE_ITER (notif_event_p) *iter,
-                         struct notif_event *event,
-                         void *data)
+static bool
+remove_all_on_match_ptid (struct notif_event *event, ptid_t filter_ptid)
 {
-  ptid_t filter_ptid = *(ptid_t *) data;
   struct vstop_notif *vstop_event = (struct vstop_notif *) event;
 
-  if (vstop_event->ptid.matches (filter_ptid))
-    {
-      if (q->free_func != NULL)
-       q->free_func (event);
-
-      QUEUE_remove_elem (notif_event_p, q, iter);
-    }
-
-  return 1;
+  return vstop_event->ptid.matches (filter_ptid);
 }
 
 /* See server.h.  */
@@ -207,8 +191,19 @@ remove_all_on_match_ptid (QUEUE (notif_event_p) *q,
 void
 discard_queued_stop_replies (ptid_t ptid)
 {
-  QUEUE_iterate (notif_event_p, notif_stop.queue,
-                remove_all_on_match_ptid, &ptid);
+  std::list<notif_event *>::iterator iter, next, end;
+  end = notif_stop.queue.end ();
+  for (iter = notif_stop.queue.begin (); iter != end; iter = next)
+    {
+      next = iter;
+      ++next;
+
+      if (remove_all_on_match_ptid (*iter, ptid))
+       {
+         delete *iter;
+         notif_stop.queue.erase (iter);
+       }
+    }
 }
 
 static void
@@ -219,27 +214,23 @@ vstop_notif_reply (struct notif_event *event, char *own_buf)
   prepare_resume_reply (own_buf, vstop->ptid, &vstop->status);
 }
 
-/* QUEUE_iterate callback helper for in_queued_stop_replies.  */
+/* Helper for in_queued_stop_replies.  */
 
-static int
-in_queued_stop_replies_ptid (QUEUE (notif_event_p) *q,
-                            QUEUE_ITER (notif_event_p) *iter,
-                            struct notif_event *event,
-                            void *data)
+static bool
+in_queued_stop_replies_ptid (struct notif_event *event, ptid_t filter_ptid)
 {
-  ptid_t filter_ptid = *(ptid_t *) data;
   struct vstop_notif *vstop_event = (struct vstop_notif *) event;
 
   if (vstop_event->ptid.matches (filter_ptid))
-    return 0;
+    return true;
 
   /* Don't resume fork children that GDB does not know about yet.  */
   if ((vstop_event->status.kind == TARGET_WAITKIND_FORKED
        || vstop_event->status.kind == TARGET_WAITKIND_VFORKED)
       && vstop_event->status.value.related_pid.matches (filter_ptid))
-    return 0;
+    return true;
 
-  return 1;
+  return false;
 }
 
 /* See server.h.  */
@@ -247,13 +238,18 @@ in_queued_stop_replies_ptid (QUEUE (notif_event_p) *q,
 int
 in_queued_stop_replies (ptid_t ptid)
 {
-  return !QUEUE_iterate (notif_event_p, notif_stop.queue,
-                        in_queued_stop_replies_ptid, &ptid);
+  for (notif_event *event : notif_stop.queue)
+    {
+      if (in_queued_stop_replies_ptid (event, ptid))
+       return true;
+    }
+
+  return false;
 }
 
 struct notif_server notif_stop =
 {
-  "vStopped", "Stop", NULL, vstop_notif_reply,
+  "vStopped", "Stop", {}, vstop_notif_reply,
 };
 
 static int
@@ -3247,14 +3243,13 @@ queue_stop_reply_callback (thread_info *thread)
      manage the thread's last_status field.  */
   if (the_target->thread_stopped == NULL)
     {
-      struct vstop_notif *new_notif = XNEW (struct vstop_notif);
+      struct vstop_notif *new_notif = new struct vstop_notif;
 
       new_notif->ptid = thread->id;
       new_notif->status = thread->last_status;
       /* Pass the last stop reply back to GDB, but don't notify
         yet.  */
-      notif_event_enque (&notif_stop,
-                        (struct notif_event *) new_notif);
+      notif_event_enque (&notif_stop, new_notif);
     }
   else
     {
@@ -3789,7 +3784,6 @@ captured_main (int argc, char *argv[])
   initialize_event_loop ();
   if (target_supports_tracepoints ())
     initialize_tracepoint ();
-  initialize_notif ();
 
   mem_buf = (unsigned char *) xmalloc (PBUFSIZ);
 
@@ -4412,12 +4406,12 @@ handle_serial_event (int err, gdb_client_data client_data)
 static void
 push_stop_notification (ptid_t ptid, struct target_waitstatus *status)
 {
-  struct vstop_notif *vstop_notif = XNEW (struct vstop_notif);
+  struct vstop_notif *vstop_notif = new struct vstop_notif;
 
   vstop_notif->status = *status;
   vstop_notif->ptid = ptid;
   /* Push Stop notification.  */
-  notif_push (&notif_stop, (struct notif_event *) vstop_notif);
+  notif_push (&notif_stop, vstop_notif);
 }
 
 /* Event-loop callback for target events.  */