+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.
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);
}
/* 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);
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 ());
}
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);
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);
-}
#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. */
/* 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);
void notif_event_enque (struct notif_server *notif,
struct notif_event *event);
-void initialize_notif (void);
-
#endif /* GDBSERVER_NOTIF_H */
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;
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;
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 (¬if_stop, (struct notif_event *) new_notif);
+ notif_event_enque (¬if_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. */
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
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. */
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
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 (¬if_stop,
- (struct notif_event *) new_notif);
+ notif_event_enque (¬if_stop, new_notif);
}
else
{
initialize_event_loop ();
if (target_supports_tracepoints ())
initialize_tracepoint ();
- initialize_notif ();
mem_buf = (unsigned char *) xmalloc (PBUFSIZ);
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 (¬if_stop, (struct notif_event *) vstop_notif);
+ notif_push (¬if_stop, vstop_notif);
}
/* Event-loop callback for target events. */