about summary refs log tree commit diff
path: root/nptl/sysdeps/unix/sysv/linux/register-atfork.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-04-05 09:36:56 +0000
committerUlrich Drepper <drepper@redhat.com>2003-04-05 09:36:56 +0000
commit54e0138f7f9ff016d3cb6b2cb02a3ca2a727b6e7 (patch)
tree80626ba7cdf1e2b1bbb1d1ef3481b62f9a85b17e /nptl/sysdeps/unix/sysv/linux/register-atfork.c
parentb22d701bb72b928526efff83c019b912f469af72 (diff)
downloadglibc-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/linux/register-atfork.c')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/register-atfork.c52
1 files changed, 47 insertions, 5 deletions
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);
     }