diff options
Diffstat (limited to 'gdbsupport')
-rw-r--r-- | gdbsupport/cleanups.cc | 122 | ||||
-rw-r--r-- | gdbsupport/cleanups.h | 17 |
2 files changed, 15 insertions, 124 deletions
diff --git a/gdbsupport/cleanups.cc b/gdbsupport/cleanups.cc index 619db02..cc14523 100644 --- a/gdbsupport/cleanups.cc +++ b/gdbsupport/cleanups.cc @@ -19,126 +19,26 @@ #include "common-defs.h" #include "cleanups.h" +#include <vector> -/* The cleanup list records things that have to be undone - if an error happens (descriptors to be closed, memory to be freed, etc.) - Each link in the chain records a function to call and an - argument to give it. +/* All the cleanup functions. */ - Use make_cleanup to add an element to the cleanup chain. - Use do_cleanups to do all cleanup actions back to a given - point in the chain. Use discard_cleanups to remove cleanups - from the chain back to a given point, not doing them. +static std::vector<std::function<void ()>> all_cleanups; - If the argument is pointer to allocated memory, then you need - to additionally set the 'free_arg' member to a function that will - free that memory. This function will be called both when the cleanup - is executed and when it's discarded. */ +/* See cleanups.h. */ -struct cleanup -{ - struct cleanup *next; - void (*function) (void *); - void (*free_arg) (void *); - void *arg; -}; - -/* Used to mark the end of a cleanup chain. - The value is chosen so that it: - - is non-NULL so that make_cleanup never returns NULL, - - causes a segv if dereferenced - [though this won't catch errors that a value of, say, - ((struct cleanup *) -1) will] - - displays as something useful when printed in gdb. - This is const for a bit of extra robustness. - It is initialized to coax gcc into putting it into .rodata. - All fields are initialized to survive -Wextra. */ -static const struct cleanup sentinel_cleanup = { 0, 0, 0, 0 }; - -/* Handy macro to use when referring to sentinel_cleanup. */ -#define SENTINEL_CLEANUP ((struct cleanup *) &sentinel_cleanup) - -/* Chain of cleanup actions established with make_final_cleanup, - to be executed when gdb exits. */ -static struct cleanup *final_cleanup_chain = SENTINEL_CLEANUP; - -/* Main worker routine to create a cleanup. - PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain. - FUNCTION is the function to call to perform the cleanup. - ARG is passed to FUNCTION when called. - FREE_ARG, if non-NULL, is called after the cleanup is performed. - - The result is a pointer to the previous chain pointer - to be passed later to do_cleanups or discard_cleanups. */ - -static struct cleanup * -make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function, - void *arg, void (*free_arg) (void *)) -{ - struct cleanup *newobj = XNEW (struct cleanup); - struct cleanup *old_chain = *pmy_chain; - - newobj->next = *pmy_chain; - newobj->function = function; - newobj->free_arg = free_arg; - newobj->arg = arg; - *pmy_chain = newobj; - - gdb_assert (old_chain != NULL); - return old_chain; -} - -/* Worker routine to create a cleanup without a destructor. - PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain. - FUNCTION is the function to call to perform the cleanup. - ARG is passed to FUNCTION when called. - - The result is a pointer to the previous chain pointer - to be passed later to do_cleanups or discard_cleanups. */ - -static struct cleanup * -make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function, - void *arg) -{ - return make_my_cleanup2 (pmy_chain, function, arg, NULL); -} - -/* Add a new cleanup to the final cleanup_chain, - and return the previous chain pointer - to be passed later to do_cleanups or discard_cleanups. - Args are FUNCTION to clean up with, and ARG to pass to it. */ - -struct cleanup * -make_final_cleanup (make_cleanup_ftype *function, void *arg) -{ - return make_my_cleanup (&final_cleanup_chain, function, arg); -} - -/* Worker routine to perform cleanups. - PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain. - OLD_CHAIN is the result of a "make" cleanup routine. - Cleanups are performed until we get back to the old end of the chain. */ - -static void -do_my_cleanups (struct cleanup **pmy_chain, - struct cleanup *old_chain) +void +add_final_cleanup (std::function<void ()> &&func) { - struct cleanup *ptr; - - while ((ptr = *pmy_chain) != old_chain) - { - *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); - } + all_cleanups.emplace_back (std::move (func)); } -/* Discard final cleanups and do the actions they describe. */ +/* See cleanups.h. */ void do_final_cleanups () { - do_my_cleanups (&final_cleanup_chain, SENTINEL_CLEANUP); + for (auto &func : all_cleanups) + func (); + all_cleanups.clear (); } diff --git a/gdbsupport/cleanups.h b/gdbsupport/cleanups.h index 3e64f7d..985cf81 100644 --- a/gdbsupport/cleanups.h +++ b/gdbsupport/cleanups.h @@ -19,21 +19,12 @@ #ifndef COMMON_CLEANUPS_H #define COMMON_CLEANUPS_H -/* Outside of cleanups.c, this is an opaque type. */ -struct cleanup; +#include <functional> -/* NOTE: cagney/2000-03-04: This typedef is strictly for the - make_cleanup function declarations below. Do not use this typedef - as a cast when passing functions into the make_cleanup() code. - Instead either use a bounce function or add a wrapper function. - Calling a f(char*) function with f(void*) is non-portable. */ -typedef void (make_cleanup_ftype) (void *); - -/* Function type for the dtor in make_cleanup_dtor. */ -typedef void (make_cleanup_dtor_ftype) (void *); - -extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *); +/* Register a function that will be called on exit. */ +extern void add_final_cleanup (std::function<void ()> &&func); +/* Run all the registered functions. */ extern void do_final_cleanups (); #endif /* COMMON_CLEANUPS_H */ |