[1/4] Use std::list for event notifications in gdbserver

Message ID 20190408002058.10793-2-tom@tromey.com
State New, archived
Headers

Commit Message

Tom Tromey April 8, 2019, 12:20 a.m. UTC
  This changes gdbserver to use std::list rather than common/queue.h for
event notifications.

gdb/gdbserver/ChangeLog
2019-04-07  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 | 23 ++++++++++++
 gdb/gdbserver/notif.c   | 37 ++++++-------------
 gdb/gdbserver/notif.h   | 17 +++++----
 gdb/gdbserver/server.c  | 80 +++++++++++++++++++----------------------
 4 files changed, 78 insertions(+), 79 deletions(-)
  

Patch

diff --git a/gdb/gdbserver/notif.c b/gdb/gdbserver/notif.c
index d581ccc1c0c..0b526eda503 100644
--- a/gdb/gdbserver/notif.c
+++ b/gdb/gdbserver/notif.c
@@ -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);
-}
diff --git a/gdb/gdbserver/notif.h b/gdb/gdbserver/notif.h
index 7d0767935bc..c0525126fdc 100644
--- a/gdb/gdbserver/notif.h
+++ b/gdb/gdbserver/notif.h
@@ -20,19 +20,20 @@ 
 #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 */
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index bfd120d2fb3..a0f70e42f48 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -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
@@ -3248,14 +3244,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
     {
@@ -3788,7 +3783,6 @@  captured_main (int argc, char *argv[])
   initialize_event_loop ();
   if (target_supports_tracepoints ())
     initialize_tracepoint ();
-  initialize_notif ();
 
   mem_buf = (unsigned char *) xmalloc (PBUFSIZ);
 
@@ -4413,12 +4407,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.  */