diff options
author | Ulrich Drepper <drepper@redhat.com> | 2003-04-05 09:36:56 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2003-04-05 09:36:56 +0000 |
commit | 54e0138f7f9ff016d3cb6b2cb02a3ca2a727b6e7 (patch) | |
tree | 80626ba7cdf1e2b1bbb1d1ef3481b62f9a85b17e /nptl/sysdeps/unix/sysv | |
parent | b22d701bb72b928526efff83c019b912f469af72 (diff) | |
download | glibc-54e0138f7f9ff016d3cb6b2cb02a3ca2a727b6e7.tar.gz glibc-54e0138f7f9ff016d3cb6b2cb02a3ca2a727b6e7.tar.xz glibc-54e0138f7f9ff016d3cb6b2cb02a3ca2a727b6e7.zip |
Update.
2003-04-05 Ulrich Drepper <drepper@redhat.com> * malloc/thread-m.h [PTHREAD_MUTEX_INITIALIZER]: If HAVE_register_atfork_malloc is defined use __register_atfork_malloc instead of __register_atfork.
Diffstat (limited to 'nptl/sysdeps/unix/sysv')
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/fork.h | 9 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/register-atfork.c | 52 |
2 files changed, 54 insertions, 7 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/fork.h b/nptl/sysdeps/unix/sysv/linux/fork.h index f3f4c38a55..e59ae87964 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 2f63c781ab..6dbc163175 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); } |