summaryrefslogtreecommitdiffstats
path: root/lib/libkse/thread
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2003-08-10 22:20:41 +0000
committerdavidxu <davidxu@FreeBSD.org>2003-08-10 22:20:41 +0000
commitb614f44d781a853409b62290cda1b2e3e0245b86 (patch)
treede14605af1cfd189b4903e40961ad3e87a33c31e /lib/libkse/thread
parent349a8e7e9bf3b0f9536820ffb38e4c2c85e411a6 (diff)
downloadFreeBSD-src-b614f44d781a853409b62290cda1b2e3e0245b86.zip
FreeBSD-src-b614f44d781a853409b62290cda1b2e3e0245b86.tar.gz
If thread mode is not activated yet, just call __sys_fork() directly,
otherwise masks all signals until fork() returns, in child process, we reset library state before restoring signal masks until we reach a safe to point. Reviewed by: deischen
Diffstat (limited to 'lib/libkse/thread')
-rw-r--r--lib/libkse/thread/thr_fork.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/lib/libkse/thread/thr_fork.c b/lib/libkse/thread/thr_fork.c
index a279621..6408fef 100644
--- a/lib/libkse/thread/thr_fork.c
+++ b/lib/libkse/thread/thr_fork.c
@@ -37,6 +37,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
+#include <sys/signalvar.h>
#include "thr_private.h"
__weak_reference(_fork, fork);
@@ -44,15 +45,35 @@ __weak_reference(_fork, fork);
pid_t
_fork(void)
{
+ sigset_t sigset, oldset;
struct pthread *curthread;
pid_t ret;
+ if (!_kse_isthreaded())
+ return (__sys_fork());
+
curthread = _get_curthread();
+ /*
+ * Masks all signals until we reach a safe point in
+ * _kse_single_thread, and the signal masks will be
+ * restored in that function, for M:N thread, all
+ * signals were already masked in kernel atomically,
+ * we only need to do this for bound thread.
+ */
+ if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) {
+ SIGFILLSET(sigset);
+ __sys_sigprocmask(SIG_SETMASK, &sigset, &oldset);
+ }
/* Fork a new process: */
- if ((ret = __sys_fork()) == 0)
+ if ((ret = __sys_fork()) == 0) {
/* Child process */
_kse_single_thread(curthread);
+ /* Kernel signal mask is restored in _kse_single_thread */
+ } else {
+ if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)
+ __sys_sigprocmask(SIG_SETMASK, &oldset, NULL);
+ }
/* Return the process ID: */
return (ret);
OpenPOWER on IntegriCloud