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:
parent
9799571ecb
commit
32603266e5
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
80
gdb/remote.c
80
gdb/remote.c
|
@ -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 ® : 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 ® : stop_reply->regcache)
|
||||||
VEC_iterate (cached_reg_t, stop_reply->regcache, ix, reg);
|
{
|
||||||
ix++)
|
regcache->raw_supply (reg.num, reg.data);
|
||||||
{
|
xfree (reg.data);
|
||||||
regcache->raw_supply (reg->num, 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue