gdb/continuations: use lambdas instead of function pointers

Use lambdas and std::list to track inferior continuations.  This is a
refactoring.

gdb/ChangeLog:
2021-04-22  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>

	* inferior.h (class inferior) <continuations>: Change the type
	to be an std::list of std::function's.
	Update the references and uses below.
	* continuations.c (struct continuation): Delete.
	(make_continuation): Delete.
	(do_my_continuations_1): Delete.
	(do_my_continuations): Delete.
	(discard_my_continuations_1): Delete.
	(discard_my_continuations): Delete.
	(add_inferior_continuation): Update.
	(do_all_inferior_continuations): Update.
	(discard_all_inferior_continuations): Update.
	* continuations.h (add_inferior_continuation): Update to take
	an std::function as the parameter.
	* infcmd.c (struct attach_command_continuation_args): Delete.
	(attach_command_continuation): Delete.
	(attach_command_continuation_free_args): Delete.
	(attach_command): Update.
	(notice_new_inferior): Update.
This commit is contained in:
Tankut Baris Aktemur 2021-04-22 17:22:39 +02:00
parent 1194676e0b
commit c4c493de2b
5 changed files with 48 additions and 143 deletions

View file

@ -1,3 +1,25 @@
2021-04-22 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
* inferior.h (class inferior) <continuations>: Change the type
to be an std::list of std::function's.
Update the references and uses below.
* continuations.c (struct continuation): Delete.
(make_continuation): Delete.
(do_my_continuations_1): Delete.
(do_my_continuations): Delete.
(discard_my_continuations_1): Delete.
(discard_my_continuations): Delete.
(add_inferior_continuation): Update.
(do_all_inferior_continuations): Update.
(discard_all_inferior_continuations): Update.
* continuations.h (add_inferior_continuation): Update to take
an std::function as the parameter.
* infcmd.c (struct attach_command_continuation_args): Delete.
(attach_command_continuation): Delete.
(attach_command_continuation_free_args): Delete.
(attach_command): Update.
(notice_new_inferior): Update.
2021-04-22 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
* continuations.h: Update the general comment.

View file

@ -22,98 +22,15 @@
#include "inferior.h"
#include "continuations.h"
struct continuation
{
struct continuation *next;
continuation_ftype *function;
continuation_free_arg_ftype *free_arg;
void *arg;
};
/* Add a new continuation to the continuation chain. Args are
FUNCTION to run the continuation up with, and ARG to pass to
it. */
static void
make_continuation (struct continuation **pmy_chain,
continuation_ftype *function,
void *arg, void (*free_arg) (void *))
{
struct continuation *newobj = XNEW (struct continuation);
newobj->next = *pmy_chain;
newobj->function = function;
newobj->free_arg = free_arg;
newobj->arg = arg;
*pmy_chain = newobj;
}
static void
do_my_continuations_1 (struct continuation **pmy_chain)
{
struct continuation *ptr;
while ((ptr = *pmy_chain) != NULL)
{
*pmy_chain = ptr->next; /* Do this first in case of recursion. */
(*ptr->function) (ptr->arg);
if (ptr->free_arg)
(*ptr->free_arg) (ptr->arg);
xfree (ptr);
}
}
static void
do_my_continuations (struct continuation **list)
{
struct continuation *continuations;
if (*list == NULL)
return;
/* Copy the list header into another pointer, and set the global
list header to null, so that the global list can change as a side
effect of invoking the continuations and the processing of the
preexisting continuations will not be affected. */
continuations = *list;
*list = NULL;
/* Work now on the list we have set aside. */
do_my_continuations_1 (&continuations);
}
static void
discard_my_continuations_1 (struct continuation **pmy_chain)
{
struct continuation *ptr;
while ((ptr = *pmy_chain) != NULL)
{
*pmy_chain = ptr->next;
if (ptr->free_arg)
(*ptr->free_arg) (ptr->arg);
xfree (ptr);
}
}
static void
discard_my_continuations (struct continuation **list)
{
discard_my_continuations_1 (list);
*list = NULL;
}
/* Add a continuation to the continuation list of INFERIOR. The new
continuation will be added at the front. */
void
add_inferior_continuation (continuation_ftype *hook, void *args,
continuation_free_arg_ftype *free_arg)
add_inferior_continuation (std::function<void ()> &&cont)
{
struct inferior *inf = current_inferior ();
make_continuation (&inf->continuations, hook, args, free_arg);
inf->continuations.emplace_front (std::move (cont));
}
/* Do all continuations of the current inferior. */
@ -122,7 +39,12 @@ void
do_all_inferior_continuations ()
{
struct inferior *inf = current_inferior ();
do_my_continuations (&inf->continuations);
while (!inf->continuations.empty ())
{
auto iter = inf->continuations.begin ();
(*iter) ();
inf->continuations.erase (iter);
}
}
/* Get rid of all the inferior-wide continuations of INF. */
@ -130,5 +52,5 @@ do_all_inferior_continuations ()
void
discard_all_inferior_continuations (struct inferior *inf)
{
discard_my_continuations (&inf->continuations);
inf->continuations.clear ();
}

View file

@ -20,29 +20,19 @@
#ifndef CONTINUATIONS_H
#define CONTINUATIONS_H
#include <functional>
struct inferior;
/* To continue the execution commands when running gdb asynchronously.
A continuation structure contains a pointer to a function to be called
to finish the command, once the target has stopped. Such mechanism is
used by the attach command and the remote target when a new inferior
is detected. */
/* Prototype of the continuation callback functions. ARG is the
continuation argument registered in the corresponding
add_*_continuation call. */
typedef void (continuation_ftype) (void *arg);
/* Prototype of the function responsible for releasing the argument
passed to the continuation callback functions, either when the
continuation is called, or discarded. */
typedef void (continuation_free_arg_ftype) (void *);
A continuation is an std::function to be called to finish the
command, once the target has stopped. Such mechanism is used by
the attach command and the remote target when a new inferior is
detected. */
/* Inferior specific (any thread) continuations. */
extern void add_inferior_continuation (continuation_ftype *,
void *,
continuation_free_arg_ftype *);
extern void add_inferior_continuation (std::function<void ()> &&cont);
extern void do_all_inferior_continuations ();
extern void discard_all_inferior_continuations (struct inferior *inf);

View file

@ -2540,30 +2540,6 @@ attach_post_wait (int from_tty, enum attach_post_wait_mode mode)
}
}
struct attach_command_continuation_args
{
int from_tty;
enum attach_post_wait_mode mode;
};
static void
attach_command_continuation (void *args)
{
struct attach_command_continuation_args *a
= (struct attach_command_continuation_args *) args;
attach_post_wait (a->from_tty, a->mode);
}
static void
attach_command_continuation_free_args (void *args)
{
struct attach_command_continuation_args *a
= (struct attach_command_continuation_args *) args;
xfree (a);
}
/* "attach" command entry point. Takes a program started up outside
of gdb and ``attaches'' to it. This stops it cold in its tracks
and allows us to start debugging it. */
@ -2661,8 +2637,6 @@ attach_command (const char *args, int from_tty)
E.g. Mach 3 or GNU hurd. */
if (!target_attach_no_wait ())
{
struct attach_command_continuation_args *a;
/* Careful here. See comments in inferior.h. Basically some
OSes don't ignore SIGSTOPs on continue requests anymore. We
need a way for handle_inferior_event to reset the stop_signal
@ -2671,11 +2645,10 @@ attach_command (const char *args, int from_tty)
inferior->control.stop_soon = STOP_QUIETLY_NO_SIGSTOP;
/* Wait for stop. */
a = XNEW (struct attach_command_continuation_args);
a->from_tty = from_tty;
a->mode = mode;
add_inferior_continuation (attach_command_continuation, a,
attach_command_continuation_free_args);
add_inferior_continuation ([=] ()
{
attach_post_wait (from_tty, mode);
});
/* Let infrun consider waiting for events out of this
target. */
@ -2719,7 +2692,6 @@ notice_new_inferior (thread_info *thr, int leave_running, int from_tty)
if (thr->executing)
{
struct attach_command_continuation_args *a;
struct inferior *inferior = current_inferior ();
/* We're going to install breakpoints, and poke at memory,
@ -2730,11 +2702,10 @@ notice_new_inferior (thread_info *thr, int leave_running, int from_tty)
inferior->control.stop_soon = STOP_QUIETLY_REMOTE;
/* Wait for stop before proceeding. */
a = XNEW (struct attach_command_continuation_args);
a->from_tty = from_tty;
a->mode = mode;
add_inferior_continuation (attach_command_continuation, a,
attach_command_continuation_free_args);
add_inferior_continuation ([=] ()
{
attach_post_wait (from_tty, mode);
});
return;
}

View file

@ -22,6 +22,7 @@
#define INFERIOR_H 1
#include <exception>
#include <list>
struct target_waitstatus;
struct frame_info;
@ -32,7 +33,6 @@ struct regcache;
struct ui_out;
struct terminal_info;
struct target_desc_info;
struct continuation;
struct inferior;
struct thread_info;
@ -510,7 +510,7 @@ public:
/* What is left to do for an execution command after any thread of
this inferior stops. */
continuation *continuations = NULL;
std::list<std::function<void ()>> continuations;
/* True if setup_inferior wasn't called for this inferior yet.
Until that is done, we must not access inferior memory or