internal mutexes and fork

Jonas Holmberg jonas.holmberg at axis.com
Fri Mar 28 19:10:22 UTC 2008


There's a problem with internal mutexes and fork. The child process
inherits the state of the mutexes of the parent. The malloc mutex is the
worst problem, since the child process tries to lock it in a call to
free(), see <http://www.busybox.net/lists/uclibc/2006-July/016030.html>.

I think it's time to fix this, so here's an initial patch for 0.9.29:

Index: libpthread/linuxthreads.old/pthread.c
===================================================================
RCS file:
/usr/local/cvs/linux/libs/uClibc/libpthread/linuxthreads.old/pthread.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.6.1
diff -u -r1.1.1.1 -r1.1.1.1.6.1
--- libpthread/linuxthreads.old/pthread.c       6 Aug 2007 10:59:22
-0000      1.1.1.1
+++ libpthread/linuxthreads.old/pthread.c       28 Mar 2008 11:09:32
-0000     1.1.1.1.6.1
@@ -347,6 +347,23 @@

 static int *__libc_multiple_threads_ptr;

+__UCLIBC_MUTEX_EXTERN(__malloc_lock);
+
+static void __pthread_malloc_atfork_prepare(void)
+{
+  __pthread_mutex_lock(&__malloc_lock);
+}
+
+static void __pthread_malloc_atfork_parent(void)
+{
+  __pthread_mutex_unlock(&__malloc_lock);
+}
+
+static void __pthread_malloc_atfork_child(void)
+{
+  __pthread_mutex_unlock(&__malloc_lock);
+}
+
  /* Do some minimal initialization which has to be done during the
     startup of the C library.  */
 void __pthread_initialize_minimal(void)
@@ -358,6 +375,9 @@
 #endif

     __libc_multiple_threads_ptr = __libc_pthread_init
(ptr_pthread_functions);
+
+    pthread_atfork(__pthread_malloc_atfork_prepare,
+        __pthread_malloc_atfork_parent, __pthread_malloc_atfork_child);
 }



I know you probably don't like this patch, since it only solves the
problem for malloc-standard and linuxthreads.old, so it's more an
example of one way to solve the problem and to start a discussion that
probably will lead to "the right way" (tm).

There are other internal mutexes than __malloc_lock that ought to be
handled the same way. Do you think it's the right approach to call
pthread_atfork from pthreads to lock/unlock all internal mutexes or
should an initializer for malloc and other "mutex-owners" call
pthread_atfork to lock/unlock its own mutex, perhaps from global
constructors?

/Jonas



More information about the uClibc mailing list