* cleanups.h (struct cleanup): Move to cleanups.c.
(make_cleanup_dtor_ftype): New typedef. (make_cleanup_dtor): Use it. (ALL_CLEANUPS): Replace with ... (all_cleanups): ... this. Declare. All uses updated. * cleanups.c: #include "gdb_assert.h". (sentinel_cleanup): New static global. (SENTINEL_CLEANUP): Define. (cleanup_chain, final_cleanup_chain): Initialize to SENTINEL_CLEANUP. (make_my_cleanup2): Assert result is non-NULL. (all_cleanups): New function. (save_my_cleanups): Initialize new chain to SENTINEL_CLEANUP instead of NULL.
This commit is contained in:
parent
ff188ee48b
commit
b10faa68a4
@ -1,3 +1,19 @@
|
|||||||
|
2012-04-19 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
|
* cleanups.h (struct cleanup): Move to cleanups.c.
|
||||||
|
(make_cleanup_dtor_ftype): New typedef.
|
||||||
|
(make_cleanup_dtor): Use it.
|
||||||
|
(ALL_CLEANUPS): Replace with ...
|
||||||
|
(all_cleanups): ... this. Declare. All uses updated.
|
||||||
|
* cleanups.c: #include "gdb_assert.h".
|
||||||
|
(sentinel_cleanup): New static global.
|
||||||
|
(SENTINEL_CLEANUP): Define.
|
||||||
|
(cleanup_chain, final_cleanup_chain): Initialize to SENTINEL_CLEANUP.
|
||||||
|
(make_my_cleanup2): Assert result is non-NULL.
|
||||||
|
(all_cleanups): New function.
|
||||||
|
(save_my_cleanups): Initialize new chain to SENTINEL_CLEANUP instead
|
||||||
|
of NULL.
|
||||||
|
|
||||||
2012-04-19 Pedro Alves <palves@redhat.com>
|
2012-04-19 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
* Makefile.in (GNULIB_BUILDDIR): New.
|
* Makefile.in (GNULIB_BUILDDIR): New.
|
||||||
|
@ -18,15 +18,53 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
#include "gdb_assert.h"
|
||||||
|
|
||||||
|
/* 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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
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_cleanup,
|
/* Chain of cleanup actions established with make_cleanup,
|
||||||
to be executed if an error happens. */
|
to be executed if an error happens. */
|
||||||
|
static struct cleanup *cleanup_chain = SENTINEL_CLEANUP;
|
||||||
|
|
||||||
/* Cleaned up after a failed command. */
|
/* Chain of cleanup actions established with make_final_cleanup,
|
||||||
static struct cleanup *cleanup_chain;
|
to be executed when gdb exits. */
|
||||||
|
static struct cleanup *final_cleanup_chain = SENTINEL_CLEANUP;
|
||||||
/* Cleaned up when gdb exits. */
|
|
||||||
static struct cleanup *final_cleanup_chain;
|
|
||||||
|
|
||||||
/* Main worker routine to create a cleanup.
|
/* Main worker routine to create a cleanup.
|
||||||
PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
|
PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
|
||||||
@ -51,6 +89,7 @@ make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function,
|
|||||||
new->arg = arg;
|
new->arg = arg;
|
||||||
*pmy_chain = new;
|
*pmy_chain = new;
|
||||||
|
|
||||||
|
gdb_assert (old_chain != NULL);
|
||||||
return old_chain;
|
return old_chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +159,15 @@ do_my_cleanups (struct cleanup **pmy_chain,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return a value that can be passed to do_cleanups, do_final_cleanups to
|
||||||
|
indicate perform all cleanups. */
|
||||||
|
|
||||||
|
struct cleanup *
|
||||||
|
all_cleanups (void)
|
||||||
|
{
|
||||||
|
return SENTINEL_CLEANUP;
|
||||||
|
}
|
||||||
|
|
||||||
/* Discard cleanups and do the actions they describe
|
/* Discard cleanups and do the actions they describe
|
||||||
until we get back to the point OLD_CHAIN in the cleanup_chain. */
|
until we get back to the point OLD_CHAIN in the cleanup_chain. */
|
||||||
|
|
||||||
@ -185,7 +233,7 @@ save_my_cleanups (struct cleanup **pmy_chain)
|
|||||||
{
|
{
|
||||||
struct cleanup *old_chain = *pmy_chain;
|
struct cleanup *old_chain = *pmy_chain;
|
||||||
|
|
||||||
*pmy_chain = 0;
|
*pmy_chain = SENTINEL_CLEANUP;
|
||||||
return old_chain;
|
return old_chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,28 +19,8 @@
|
|||||||
#ifndef CLEANUPS_H
|
#ifndef CLEANUPS_H
|
||||||
#define CLEANUPS_H
|
#define CLEANUPS_H
|
||||||
|
|
||||||
/* The cleanup list records things that have to be undone
|
/* Outside of cleanups.c, this is an opaque type. */
|
||||||
if an error happens (descriptors to be closed, memory to be freed, etc.)
|
struct cleanup;
|
||||||
Each link in the chain records a function to call and an
|
|
||||||
argument to give it.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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. */
|
|
||||||
|
|
||||||
struct cleanup
|
|
||||||
{
|
|
||||||
struct cleanup *next;
|
|
||||||
void (*function) (void *);
|
|
||||||
void (*free_arg) (void *);
|
|
||||||
void *arg;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* NOTE: cagney/2000-03-04: This typedef is strictly for the
|
/* NOTE: cagney/2000-03-04: This typedef is strictly for the
|
||||||
make_cleanup function declarations below. Do not use this typedef
|
make_cleanup function declarations below. Do not use this typedef
|
||||||
@ -49,21 +29,25 @@ struct cleanup
|
|||||||
Calling a f(char*) function with f(void*) is non-portable. */
|
Calling a f(char*) function with f(void*) is non-portable. */
|
||||||
typedef void (make_cleanup_ftype) (void *);
|
typedef void (make_cleanup_ftype) (void *);
|
||||||
|
|
||||||
|
/* Function type for the dtor in make_cleanup_dtor. */
|
||||||
|
typedef void (make_cleanup_dtor_ftype) (void *);
|
||||||
|
|
||||||
/* WARNING: The result of the "make cleanup" routines is not the intuitive
|
/* WARNING: The result of the "make cleanup" routines is not the intuitive
|
||||||
choice of being a handle on the just-created cleanup. Instead it is an
|
choice of being a handle on the just-created cleanup. Instead it is an
|
||||||
opaque handle of the cleanup mechanism and represents all cleanups created
|
opaque handle of the cleanup mechanism and represents all cleanups created
|
||||||
from that point onwards. */
|
from that point onwards.
|
||||||
|
The result is guaranteed to be non-NULL though. */
|
||||||
|
|
||||||
extern struct cleanup *make_cleanup (make_cleanup_ftype *, void *);
|
extern struct cleanup *make_cleanup (make_cleanup_ftype *, void *);
|
||||||
|
|
||||||
extern struct cleanup *make_cleanup_dtor (make_cleanup_ftype *, void *,
|
extern struct cleanup *make_cleanup_dtor (make_cleanup_ftype *, void *,
|
||||||
void (*dtor) (void *));
|
make_cleanup_dtor_ftype *);
|
||||||
|
|
||||||
extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *);
|
extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *);
|
||||||
|
|
||||||
/* A special value to pass to do_cleanups and do_final_cleanups
|
/* A special value to pass to do_cleanups and do_final_cleanups
|
||||||
to tell them to do all cleanups. */
|
to tell them to do all cleanups. */
|
||||||
#define ALL_CLEANUPS ((struct cleanup *)0)
|
extern struct cleanup *all_cleanups (void);
|
||||||
|
|
||||||
extern void do_cleanups (struct cleanup *);
|
extern void do_cleanups (struct cleanup *);
|
||||||
extern void do_final_cleanups (struct cleanup *);
|
extern void do_final_cleanups (struct cleanup *);
|
||||||
|
Loading…
Reference in New Issue
Block a user