diff options
author | Kurt Miller <kurt@cvs.openbsd.org> | 2008-04-04 19:30:42 +0000 |
---|---|---|
committer | Kurt Miller <kurt@cvs.openbsd.org> | 2008-04-04 19:30:42 +0000 |
commit | 2419060533a4e33e9985400be7adb6ab4ce3263b (patch) | |
tree | 7a2a9df18a429efb139fadf314d6b2368bde2e4e /lib/libpthread | |
parent | a56291bdcb56c4ec3dbbb489004badcd40f4c656 (diff) |
- do not call pthread_atfork(3) handlers when a multithreaded program
calls vfork(2). "untested, but looks OK" marc@
- document vfork(2), popen(3) and system(3) don't call atfork handlers
in multithreaded programs. okay jmc@
Diffstat (limited to 'lib/libpthread')
-rw-r--r-- | lib/libpthread/uthread/uthread_fork.c | 55 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_vfork.c | 21 |
2 files changed, 49 insertions, 27 deletions
diff --git a/lib/libpthread/uthread/uthread_fork.c b/lib/libpthread/uthread/uthread_fork.c index 5234845a207..4eceda4c86c 100644 --- a/lib/libpthread/uthread/uthread_fork.c +++ b/lib/libpthread/uthread/uthread_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_fork.c,v 1.18 2007/11/20 19:35:37 deraadt Exp $ */ +/* $OpenBSD: uthread_fork.c,v 1.19 2008/04/04 19:30:41 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -46,17 +46,8 @@ pid_t _dofork(int vfork); pid_t fork(void) { - return (_dofork(0)); -} - -pid_t -_dofork(int vfork) -{ - struct pthread *curthread = _get_curthread(); + pid_t pid; struct pthread_atfork *af; - int i, flags; - pid_t ret; - pthread_t pthread; /* * Defer signals to protect the scheduling queues from access @@ -72,15 +63,40 @@ _dofork(int vfork) af->prepare(); } - /* Fork a new process: */ - if ((ret = (vfork ? _thread_sys_vfork() : _thread_sys_fork())) != 0) { + if ((pid = _dofork(0)) == 0) { + /* Run down atfork child handlers. */ + TAILQ_FOREACH(af, &_atfork_list, qe) { + if (af->child != NULL) + af->child(); + } + _mutex_reinit(&_atfork_mutex); + } else { /* Run down atfork parent handlers. */ TAILQ_FOREACH(af, &_atfork_list, qe) { if (af->parent != NULL) af->parent(); } pthread_mutex_unlock(&_atfork_mutex); - } else { + } + + /* + * Undefer and handle pending signals, yielding if necessary: + */ + _thread_kern_sig_undefer(); + + return(pid); +} + +pid_t +_dofork(int vfork) +{ + struct pthread *curthread = _get_curthread(); + int i, flags; + pid_t ret; + pthread_t pthread; + + /* Fork a new process and reset child's state */ + if ((ret = (vfork ? _thread_sys_vfork() : _thread_sys_fork())) == 0) { /* Close the pthread kernel pipe: */ _thread_sys_close(_thread_kern_pipe[0]); _thread_sys_close(_thread_kern_pipe[1]); @@ -210,19 +226,8 @@ _dofork(int vfork) } } } - /* Run down atfork child handlers. */ - TAILQ_FOREACH(af, &_atfork_list, qe) { - if (af->child != NULL) - af->child(); - } - _mutex_reinit(&_atfork_mutex); } - /* - * Undefer and handle pending signals, yielding if necessary: - */ - _thread_kern_sig_undefer(); - /* Return the process ID: */ return (ret); } diff --git a/lib/libpthread/uthread/uthread_vfork.c b/lib/libpthread/uthread/uthread_vfork.c index 10f8586536a..545bcdc96ba 100644 --- a/lib/libpthread/uthread/uthread_vfork.c +++ b/lib/libpthread/uthread/uthread_vfork.c @@ -1,12 +1,29 @@ -/* $OpenBSD: uthread_vfork.c,v 1.3 2007/11/20 19:35:37 deraadt Exp $ */ +/* $OpenBSD: uthread_vfork.c,v 1.4 2008/04/04 19:30:41 kurt Exp $ */ #include <unistd.h> #ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" pid_t _dofork(int vfork); pid_t vfork(void) { - return (_dofork(1)); + pid_t pid; + + /* + * Defer signals to protect the scheduling queues from access + * by the signal handler: + */ + _thread_kern_sig_defer(); + + pid = _dofork(1); + + /* + * Undefer and handle pending signals, yielding if necessary: + */ + _thread_kern_sig_undefer(); + + return (pid); } #endif |