aboutsummaryrefslogtreecommitdiff
path: root/nptl
diff options
context:
space:
mode:
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog9
-rw-r--r--nptl/sysdeps/unix/sysv/linux/fork.h9
-rw-r--r--nptl/sysdeps/unix/sysv/linux/register-atfork.c52
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);
}