mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-02 12:01:32 +01:00
Add code to allow for late memory cleanup.
* common/init.c (mem_cleanup_item_t): New. (run_mem_cleanup): New. (_init_common_subsystems): Add an atexit for it. (register_mem_cleanup_func): New. * g10/kbnode.c (cleanup_registered): New. (release_unused_nodes): New. (alloc_node): Call register_mem_cleanup_func. -- It is often time consuming to figure out whether still allocated memory at process termination is fine (e.g. a cache) or a problem. To help for that register_mem_cleanup_func may now be used to cleanup such memory. The run time of the program will be longer; if that turns out to be a problem we can change the code to only run in debugging mode.
This commit is contained in:
parent
44159b681f
commit
2739834206
@ -46,6 +46,21 @@
|
||||
|
||||
#include "util.h"
|
||||
|
||||
/* This object is used to register memory cleanup functions.
|
||||
Technically they are not needed but they can avoid frequent
|
||||
questions about un-released memory. Note that we use the system
|
||||
malloc and not any wrappers. */
|
||||
struct mem_cleanup_item_s;
|
||||
typedef struct mem_cleanup_item_s *mem_cleanup_item_t;
|
||||
|
||||
struct mem_cleanup_item_s
|
||||
{
|
||||
mem_cleanup_item_t next;
|
||||
void (*func) (void);
|
||||
};
|
||||
|
||||
static mem_cleanup_item_t mem_cleanup_list;
|
||||
|
||||
|
||||
/* The default error source of the application. This is different
|
||||
from GPG_ERR_SOURCE_DEFAULT in that it does not depend on the
|
||||
@ -65,6 +80,36 @@ sleep_on_exit (void)
|
||||
#endif /*HAVE_W32CE_SYSTEM*/
|
||||
|
||||
|
||||
static void
|
||||
run_mem_cleanup (void)
|
||||
{
|
||||
mem_cleanup_item_t next;
|
||||
|
||||
while (mem_cleanup_list)
|
||||
{
|
||||
next = mem_cleanup_list->next;
|
||||
mem_cleanup_list->func ();
|
||||
free (mem_cleanup_list);
|
||||
mem_cleanup_list = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
register_mem_cleanup_func (void (*func)(void))
|
||||
{
|
||||
mem_cleanup_item_t item;
|
||||
|
||||
item = malloc (sizeof *item);
|
||||
if (item)
|
||||
{
|
||||
item->func = func;
|
||||
item->next = mem_cleanup_list;
|
||||
mem_cleanup_list = item;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If STRING is not NULL write string to es_stdout or es_stderr. MODE
|
||||
must be 1 or 2. If STRING is NULL flush the respective stream. */
|
||||
static int
|
||||
@ -100,6 +145,8 @@ _init_common_subsystems (gpg_err_source_t errsource, int *argcp, char ***argvp)
|
||||
/* Store the error source in a gloabl variable. */
|
||||
default_errsource = errsource;
|
||||
|
||||
atexit (run_mem_cleanup);
|
||||
|
||||
/* Try to auto set the character set. */
|
||||
set_native_charset (NULL);
|
||||
|
||||
|
@ -36,6 +36,8 @@
|
||||
# error GPG_ERR_SOURCE_DEFAULT has default value
|
||||
#endif
|
||||
|
||||
void register_mem_cleanup_func (void (*func)(void));
|
||||
|
||||
void _init_common_subsystems (gpg_err_source_t errsource,
|
||||
int *argcp, char ***argvp);
|
||||
#define init_common_subsystems(a,b) \
|
||||
|
37
g10/kbnode.c
37
g10/kbnode.c
@ -31,18 +31,40 @@
|
||||
|
||||
#define USE_UNUSED_NODES 1
|
||||
|
||||
static int cleanup_registered;
|
||||
static KBNODE unused_nodes;
|
||||
|
||||
static KBNODE
|
||||
alloc_node(void)
|
||||
#if USE_UNUSED_NODES
|
||||
static void
|
||||
release_unused_nodes (void)
|
||||
{
|
||||
KBNODE n;
|
||||
while (unused_nodes)
|
||||
{
|
||||
kbnode_t next = unused_nodes->next;
|
||||
xfree (unused_nodes);
|
||||
unused_nodes = next;
|
||||
}
|
||||
}
|
||||
#endif /*USE_UNUSED_NODES*/
|
||||
|
||||
|
||||
static kbnode_t
|
||||
alloc_node (void)
|
||||
{
|
||||
kbnode_t n;
|
||||
|
||||
n = unused_nodes;
|
||||
if( n )
|
||||
if (n)
|
||||
unused_nodes = n->next;
|
||||
else
|
||||
n = xmalloc( sizeof *n );
|
||||
{
|
||||
if (!cleanup_registered)
|
||||
{
|
||||
cleanup_registered = 1;
|
||||
register_mem_cleanup_func (release_unused_nodes);
|
||||
}
|
||||
n = xmalloc (sizeof *n);
|
||||
}
|
||||
n->next = NULL;
|
||||
n->pkt = NULL;
|
||||
n->flag = 0;
|
||||
@ -54,12 +76,13 @@ alloc_node(void)
|
||||
static void
|
||||
free_node( KBNODE n )
|
||||
{
|
||||
if( n ) {
|
||||
if (n)
|
||||
{
|
||||
#if USE_UNUSED_NODES
|
||||
n->next = unused_nodes;
|
||||
unused_nodes = n;
|
||||
#else
|
||||
xfree( n );
|
||||
xfree (n);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user