LinuxThreads bugfix---fork() vs. pthread_once.
Kaz Kylheku
kaz@ashi.footprints.net
Wed Mar 22 08:42:00 GMT 2000
I have discovered a defect related to the handling of the global mutex
``once_masterlock'' when one of the threads does a fork. As in, it's not done.
As a result, a deadlock will occur in the child process if the fork happens
while the lock is held, and the child executes pthread_once.
This is the patch. Basically, I have added a function which resets the
pthread once condition variable and mutex in the child process and hooked
it into the fork() override function.
Index: internals.h
===================================================================
RCS file: /cvs/glibc/libc/linuxthreads/internals.h,v
retrieving revision 1.15.2.9
diff -u -r1.15.2.9 internals.h
--- internals.h 2000/01/12 11:57:16 1.15.2.9
+++ internals.h 2000/03/22 16:38:25
@@ -387,6 +387,7 @@
int __pthread_manager_event(void *reqfd);
void __pthread_manager_sighandler(int sig);
void __pthread_reset_main_thread(void);
+void __pthread_reset_pthread_once(void);
void __fresetlockfiles(void);
void __pthread_manager_adjust_prio(int thread_prio);
void __pthread_set_own_extricate_if(pthread_descr self, pthread_extricate_if *peif);
Index: mutex.c
===================================================================
RCS file: /cvs/glibc/libc/linuxthreads/mutex.c,v
retrieving revision 1.9.2.2
diff -u -r1.9.2.2 mutex.c
--- mutex.c 2000/03/16 21:29:42 1.9.2.2
+++ mutex.c 2000/03/22 16:38:25
@@ -223,3 +223,15 @@
return 0;
}
strong_alias (__pthread_once, pthread_once)
+
+/*
+ * This is called in the child process after a fork to make
+ * sure that the global mutex pthread_once is not held,
+ * and that the condition variable is reset to an initial state.
+ */
+
+void __pthread_reset_pthread_once(void)
+{
+ pthread_mutex_init(&once_masterlock, NULL);
+ pthread_cond_init(&once_finished, NULL);
+}
Index: ptfork.c
===================================================================
RCS file: /cvs/glibc/libc/linuxthreads/ptfork.c,v
retrieving revision 1.3.2.2
diff -u -r1.3.2.2 ptfork.c
--- ptfork.c 1999/09/05 17:36:30 1.3.2.2
+++ ptfork.c 2000/03/22 16:38:25
@@ -89,6 +89,7 @@
pid = __libc_fork();
if (pid == 0) {
__pthread_reset_main_thread();
+ __pthread_reset_pthread_once();
__fresetlockfiles();
pthread_call_handlers(child);
} else {
More information about the Libc-alpha
mailing list