+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.
#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. */
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. */
void
discard_all_inferior_continuations (struct inferior *inf)
{
- discard_my_continuations (&inf->continuations);
+ inf->continuations.clear ();
}
#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);
}
}
-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. */
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
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. */
if (thr->executing)
{
- struct attach_command_continuation_args *a;
struct inferior *inferior = current_inferior ();
/* We're going to install breakpoints, and poke at memory,
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;
}
#define INFERIOR_H 1
#include <exception>
+#include <list>
struct target_waitstatus;
struct frame_info;
struct ui_out;
struct terminal_info;
struct target_desc_info;
-struct continuation;
struct inferior;
struct thread_info;
/* 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