diff options
Diffstat (limited to 'nptl')
-rw-r--r-- | nptl/ChangeLog | 9 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/fork.h | 9 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/register-atfork.c | 52 |
3 files changed, 63 insertions, 7 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 7273ece..c798977 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,12 @@ +2003-04-05 Ulrich Drepper <drepper@redhat.com> + + * sysdeps/unix/sysv/linux/register-atfork.c: Define malloc_prepare, + malloc_parent, and malloc_child statically. + (__register_atfork_malloc): New function. + (free_mem): Don't free any of the malloc_* variables on the list. + * sysdeps/unix/sysv/linux/fork.h: Declare __register_atfork_malloc. + Define HAVE_register_atfork_malloc. + 2003-04-04 Ulrich Drepper <drepper@redhat.com> * sysdeps/pthread/createthread.c (create_thread): Add some more diff --git a/nptl/sysdeps/unix/sysv/linux/fork.h b/nptl/sysdeps/unix/sysv/linux/fork.h index f3f4c38..e59ae87 100644 --- a/nptl/sysdeps/unix/sysv/linux/fork.h +++ b/nptl/sysdeps/unix/sysv/linux/fork.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -54,4 +54,9 @@ extern int __register_atfork (void (*__prepare) (void), void (*__parent) (void), void (*__child) (void), void *dso_handle); -libc_hidden_proto (__register_atfork) + +extern void __register_atfork_malloc (void (*prepare) (void), + void (*parent) (void), + void (*child) (void), + void *dso_handle) attribute_hidden; +#define HAVE_register_atfork_malloc diff --git a/nptl/sysdeps/unix/sysv/linux/register-atfork.c b/nptl/sysdeps/unix/sysv/linux/register-atfork.c index 2f63c78..6dbc163 100644 --- a/nptl/sysdeps/unix/sysv/linux/register-atfork.c +++ b/nptl/sysdeps/unix/sysv/linux/register-atfork.c @@ -89,7 +89,45 @@ __register_atfork (prepare, parent, child, dso_handle) return 0; } -libc_hidden_def (__register_atfork) + + +/* Three static memory blocks used when registering malloc. */ +static struct fork_handler malloc_prepare; +static struct fork_handler malloc_parent; +static struct fork_handler malloc_child; + + +void +attribute_hidden +__register_atfork_malloc (prepare, parent, child, dso_handle) + void (*prepare) (void); + void (*parent) (void); + void (*child) (void); + void *dso_handle; +{ + /* Pre-fork handler. */ + malloc_prepare.handler = prepare; + malloc_prepare.dso_handle = dso_handle; + + /* Parent handler. */ + malloc_parent.handler = parent; + malloc_parent.dso_handle = dso_handle; + + /* Child handler. */ + malloc_child.handler = child; + malloc_child.dso_handle = dso_handle; + + /* Get the lock to not conflict with running forks. */ + lll_lock (__fork_lock); + + /* Now that we have all the handlers allocate enqueue them. */ + list_add_tail (&malloc_prepare.list, &__fork_prepare_list); + list_add_tail (&malloc_parent.list, &__fork_parent_list); + list_add_tail (&malloc_child.list, &__fork_child_list); + + /* Release the lock. */ + lll_unlock (__fork_lock); +} libc_freeres_fn (free_mem) @@ -104,22 +142,26 @@ libc_freeres_fn (free_mem) { list_del (runp); - free (list_entry (runp, struct fork_handler, list)); + struct fork_handler *p = list_entry (runp, struct fork_handler, list); + if (p != &malloc_prepare) + free (p); } list_for_each_prev_safe (runp, prevp, &__fork_parent_list) { list_del (runp); - free (list_entry (runp, struct fork_handler, list)); + struct fork_handler *p = list_entry (runp, struct fork_handler, list); + if (p != &malloc_parent) + free (p); } list_for_each_prev_safe (runp, prevp, &__fork_child_list) { list_del (runp); - void *p = list_entry (runp, struct fork_handler, list); - if (p != (void *) &__pthread_child_handler) + struct fork_handler *p = list_entry (runp, struct fork_handler, list); + if (p != &__pthread_child_handler && p != &malloc_child) free (p); } |