C++ify remote notification code

This C++ifies the remote notification code -- replacing function
pointers with virtual methods and using unique_ptr.  This allows for
the removal of some cleanups.

2019-03-06  Tom Tromey  <tom@tromey.com>

	* remote.c (struct stop_reply_deleter): Remove.
	(stop_reply_up): Update.
	(struct stop_reply): Derive from notif_event.  Don't typedef.
	<regcache>: Now a std::vector.
	(stop_reply_xfree): Remove.
	(stop_reply::~stop_reply): Rename from stop_reply_dtr.
	(remote_notif_stop_alloc_reply): Return a unique_ptr.  Use new.
	(remote_target::discard_pending_stop_replies): Use delete.
	(remote_target::remote_parse_stop_reply): Update.
	(remote_target::process_stop_reply): Update.
	* remote-notif.h (struct notif_event): Add virtual destructor.
	Remove "dtr" member.
	(struct notif_client) <alloc_event>: Return a unique_ptr.
	(notif_event_xfree): Don't declare.
	(notif_event_up): New typedef.
	* remote-notif.c (remote_notif_ack, remote_notif_parse): Update.
	(notif_event_xfree, do_notif_event_xfree): Remove.
	(remote_notif_state_xfree): Update.
This commit is contained in:
Tom Tromey 2019-01-23 22:16:53 -07:00
parent 9799571ecb
commit 32603266e5
4 changed files with 59 additions and 99 deletions

View File

@ -1,3 +1,24 @@
2019-03-06 Tom Tromey <tom@tromey.com>
* remote.c (struct stop_reply_deleter): Remove.
(stop_reply_up): Update.
(struct stop_reply): Derive from notif_event. Don't typedef.
<regcache>: Now a std::vector.
(stop_reply_xfree): Remove.
(stop_reply::~stop_reply): Rename from stop_reply_dtr.
(remote_notif_stop_alloc_reply): Return a unique_ptr. Use new.
(remote_target::discard_pending_stop_replies): Use delete.
(remote_target::remote_parse_stop_reply): Update.
(remote_target::process_stop_reply): Update.
* remote-notif.h (struct notif_event): Add virtual destructor.
Remove "dtr" member.
(struct notif_client) <alloc_event>: Return a unique_ptr.
(notif_event_xfree): Don't declare.
(notif_event_up): New typedef.
* remote-notif.c (remote_notif_ack, remote_notif_parse): Update.
(notif_event_xfree, do_notif_event_xfree): Remove.
(remote_notif_state_xfree): Update.
2019-03-06 Tom Tromey <tom@tromey.com> 2019-03-06 Tom Tromey <tom@tromey.com>
* infrun.c (displaced_step_clear_cleanup): Now a * infrun.c (displaced_step_clear_cleanup): Now a

View File

@ -52,8 +52,6 @@ static struct notif_client *notifs[] =
gdb_static_assert (ARRAY_SIZE (notifs) == REMOTE_NOTIF_LAST); gdb_static_assert (ARRAY_SIZE (notifs) == REMOTE_NOTIF_LAST);
static void do_notif_event_xfree (void *arg);
/* Parse the BUF for the expected notification NC, and send packet to /* Parse the BUF for the expected notification NC, and send packet to
acknowledge. */ acknowledge. */
@ -61,18 +59,14 @@ void
remote_notif_ack (remote_target *remote, remote_notif_ack (remote_target *remote,
struct notif_client *nc, const char *buf) struct notif_client *nc, const char *buf)
{ {
struct notif_event *event = nc->alloc_event (); notif_event_up event = nc->alloc_event ();
struct cleanup *old_chain
= make_cleanup (do_notif_event_xfree, event);
if (notif_debug) if (notif_debug)
fprintf_unfiltered (gdb_stdlog, "notif: ack '%s'\n", fprintf_unfiltered (gdb_stdlog, "notif: ack '%s'\n",
nc->ack_command); nc->ack_command);
nc->parse (remote, nc, buf, event); nc->parse (remote, nc, buf, event.get ());
nc->ack (remote, nc, buf, event); nc->ack (remote, nc, buf, event.release ());
discard_cleanups (old_chain);
} }
/* Parse the BUF for the expected notification NC. */ /* Parse the BUF for the expected notification NC. */
@ -81,17 +75,14 @@ struct notif_event *
remote_notif_parse (remote_target *remote, remote_notif_parse (remote_target *remote,
struct notif_client *nc, const char *buf) struct notif_client *nc, const char *buf)
{ {
struct notif_event *event = nc->alloc_event (); notif_event_up event = nc->alloc_event ();
struct cleanup *old_chain
= make_cleanup (do_notif_event_xfree, event);
if (notif_debug) if (notif_debug)
fprintf_unfiltered (gdb_stdlog, "notif: parse '%s'\n", nc->name); fprintf_unfiltered (gdb_stdlog, "notif: parse '%s'\n", nc->name);
nc->parse (remote, nc, buf, event); nc->parse (remote, nc, buf, event.get ());
discard_cleanups (old_chain); return event.release ();
return event;
} }
DEFINE_QUEUE_P (notif_client_p); DEFINE_QUEUE_P (notif_client_p);
@ -216,25 +207,6 @@ handle_notification (struct remote_notif_state *state, const char *buf)
} }
} }
/* Invoke destructor of EVENT and xfree it. */
void
notif_event_xfree (struct notif_event *event)
{
if (event != NULL && event->dtr != NULL)
event->dtr (event);
xfree (event);
}
/* Cleanup wrapper. */
static void
do_notif_event_xfree (void *arg)
{
notif_event_xfree ((struct notif_event *) arg);
}
/* Return an allocated remote_notif_state. */ /* Return an allocated remote_notif_state. */
struct remote_notif_state * struct remote_notif_state *
@ -269,7 +241,7 @@ remote_notif_state_xfree (struct remote_notif_state *state)
delete_async_event_handler (&state->get_pending_events_token); delete_async_event_handler (&state->get_pending_events_token);
for (i = 0; i < REMOTE_NOTIF_LAST; i++) for (i = 0; i < REMOTE_NOTIF_LAST; i++)
notif_event_xfree (state->pending_event[i]); delete state->pending_event[i];
xfree (state); xfree (state);
} }

View File

@ -20,17 +20,22 @@
#ifndef REMOTE_NOTIF_H #ifndef REMOTE_NOTIF_H
#define REMOTE_NOTIF_H #define REMOTE_NOTIF_H
#include <memory>
#include "common/queue.h" #include "common/queue.h"
/* An event of a type of async remote notification. */ /* An event of a type of async remote notification. */
struct notif_event struct notif_event
{ {
/* Destructor. Release everything from SELF, but not SELF virtual ~notif_event ()
itself. */ {
void (*dtr) (struct notif_event *self); }
}; };
/* A unique pointer holding a notif_event. */
typedef std::unique_ptr<notif_event> notif_event_up;
/* ID of the notif_client. */ /* ID of the notif_client. */
enum REMOTE_NOTIF_ID enum REMOTE_NOTIF_ID
@ -70,7 +75,7 @@ typedef struct notif_client
struct notif_client *self); struct notif_client *self);
/* Allocate an event. */ /* Allocate an event. */
struct notif_event *(*alloc_event) (void); notif_event_up (*alloc_event) ();
/* Id of this notif_client. */ /* Id of this notif_client. */
const enum REMOTE_NOTIF_ID id; const enum REMOTE_NOTIF_ID id;
@ -112,8 +117,6 @@ struct notif_event *remote_notif_parse (remote_target *remote,
notif_client *nc, notif_client *nc,
const char *buf); const char *buf);
void notif_event_xfree (struct notif_event *event);
void handle_notification (struct remote_notif_state *notif_state, void handle_notification (struct remote_notif_state *notif_state,
const char *buf); const char *buf);

View File

@ -96,17 +96,7 @@ struct protocol_feature;
struct packet_reg; struct packet_reg;
struct stop_reply; struct stop_reply;
static void stop_reply_xfree (struct stop_reply *); typedef std::unique_ptr<stop_reply> stop_reply_up;
struct stop_reply_deleter
{
void operator() (stop_reply *r) const
{
stop_reply_xfree (r);
}
};
typedef std::unique_ptr<stop_reply, stop_reply_deleter> stop_reply_up;
/* Generic configuration support for packets the stub optionally /* Generic configuration support for packets the stub optionally
supports. Allows the user to specify the use of the packet as well supports. Allows the user to specify the use of the packet as well
@ -6813,11 +6803,9 @@ remote_console_output (const char *msg)
gdb_flush (gdb_stdtarg); gdb_flush (gdb_stdtarg);
} }
DEF_VEC_O(cached_reg_t); struct stop_reply : public notif_event
typedef struct stop_reply
{ {
struct notif_event base; ~stop_reply ();
/* The identifier of the thread about this event */ /* The identifier of the thread about this event */
ptid_t ptid; ptid_t ptid;
@ -6836,20 +6824,14 @@ typedef struct stop_reply
efficient for those targets that provide critical registers as efficient for those targets that provide critical registers as
part of their normal status mechanism (as another roundtrip to part of their normal status mechanism (as another roundtrip to
fetch them is avoided). */ fetch them is avoided). */
VEC(cached_reg_t) *regcache; std::vector<cached_reg_t> regcache;
enum target_stop_reason stop_reason; enum target_stop_reason stop_reason;
CORE_ADDR watch_data_address; CORE_ADDR watch_data_address;
int core; int core;
} *stop_reply_p; };
static void
stop_reply_xfree (struct stop_reply *r)
{
notif_event_xfree ((struct notif_event *) r);
}
/* Return the length of the stop reply queue. */ /* Return the length of the stop reply queue. */
@ -6901,30 +6883,16 @@ remote_notif_stop_can_get_pending_events (remote_target *remote,
return 0; return 0;
} }
static void stop_reply::~stop_reply ()
stop_reply_dtr (struct notif_event *event)
{ {
struct stop_reply *r = (struct stop_reply *) event; for (cached_reg_t &reg : regcache)
cached_reg_t *reg; xfree (reg.data);
int ix;
for (ix = 0;
VEC_iterate (cached_reg_t, r->regcache, ix, reg);
ix++)
xfree (reg->data);
VEC_free (cached_reg_t, r->regcache);
} }
static struct notif_event * static notif_event_up
remote_notif_stop_alloc_reply (void) remote_notif_stop_alloc_reply ()
{ {
/* We cast to a pointer to the "base class". */ return notif_event_up (new struct stop_reply ());
struct notif_event *r = (struct notif_event *) XNEW (struct stop_reply);
r->dtr = stop_reply_dtr;
return r;
} }
/* A client of notification Stop. */ /* A client of notification Stop. */
@ -7067,7 +7035,7 @@ remote_target::discard_pending_stop_replies (struct inferior *inf)
/* Discard the in-flight notification. */ /* Discard the in-flight notification. */
if (reply != NULL && reply->ptid.pid () == inf->pid) if (reply != NULL && reply->ptid.pid () == inf->pid)
{ {
stop_reply_xfree (reply); delete reply;
rns->pending_event[notif_client_stop.id] = NULL; rns->pending_event[notif_client_stop.id] = NULL;
} }
@ -7211,7 +7179,7 @@ remote_target::remote_parse_stop_reply (const char *buf, stop_reply *event)
event->ws.kind = TARGET_WAITKIND_IGNORE; event->ws.kind = TARGET_WAITKIND_IGNORE;
event->ws.value.integer = 0; event->ws.value.integer = 0;
event->stop_reason = TARGET_STOPPED_BY_NO_REASON; event->stop_reason = TARGET_STOPPED_BY_NO_REASON;
event->regcache = NULL; event->regcache.clear ();
event->core = -1; event->core = -1;
switch (buf[0]) switch (buf[0])
@ -7447,7 +7415,7 @@ Packet: '%s'\n"),
if (fieldsize < register_size (event->arch, reg->regnum)) if (fieldsize < register_size (event->arch, reg->regnum))
warning (_("Remote reply is too short: %s"), buf); warning (_("Remote reply is too short: %s"), buf);
VEC_safe_push (cached_reg_t, event->regcache, &cached_reg); event->regcache.push_back (cached_reg);
} }
else else
{ {
@ -7663,22 +7631,18 @@ remote_target::process_stop_reply (struct stop_reply *stop_reply,
&& status->kind != TARGET_WAITKIND_NO_RESUMED) && status->kind != TARGET_WAITKIND_NO_RESUMED)
{ {
/* Expedited registers. */ /* Expedited registers. */
if (stop_reply->regcache) if (!stop_reply->regcache.empty ())
{ {
struct regcache *regcache struct regcache *regcache
= get_thread_arch_regcache (ptid, stop_reply->arch); = get_thread_arch_regcache (ptid, stop_reply->arch);
cached_reg_t *reg;
int ix;
for (ix = 0; for (cached_reg_t &reg : stop_reply->regcache)
VEC_iterate (cached_reg_t, stop_reply->regcache, ix, reg);
ix++)
{ {
regcache->raw_supply (reg->num, reg->data); regcache->raw_supply (reg.num, reg.data);
xfree (reg->data); xfree (reg.data);
} }
VEC_free (cached_reg_t, stop_reply->regcache); stop_reply->regcache.clear ();
} }
remote_notice_new_inferior (ptid, 0); remote_notice_new_inferior (ptid, 0);
@ -7689,7 +7653,7 @@ remote_target::process_stop_reply (struct stop_reply *stop_reply,
remote_thr->vcont_resumed = 0; remote_thr->vcont_resumed = 0;
} }
stop_reply_xfree (stop_reply); delete stop_reply;
return ptid; return ptid;
} }