Page MenuHomeFreeBSD

D41128.id125092.diff
No OneTemporary

D41128.id125092.diff

diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -862,7 +862,7 @@
static int curfail;
static struct timeval lastfail;
int flags, pages;
- bool killsx_locked;
+ bool killsx_locked, singlethreaded;
flags = fr->fr_flags;
pages = fr->fr_pages;
@@ -920,6 +920,7 @@
newproc = NULL;
vm2 = NULL;
killsx_locked = false;
+ singlethreaded = false;
/*
* Increment the nprocs resource before allocations occur.
@@ -954,10 +955,25 @@
* a signal to our process group until the child is visible.
*/
pg = p1->p_pgrp;
- if (sx_slock_sig(&pg->pg_killsx) != 0) {
+ if (p1->p_numthreads > 1) {
+ if (sx_try_slock(&pg->pg_killsx) != 0) {
+ killsx_locked = true;
+ } else {
+ PROC_LOCK(p1);
+ if (thread_single(p1, SINGLE_BOUNDARY)) {
+ PROC_UNLOCK(p1);
+ error = ERESTART;
+ goto fail2;
+ }
+ PROC_UNLOCK(p1);
+ singlethreaded = true;
+ }
+ }
+ if (!killsx_locked && sx_slock_sig(&pg->pg_killsx) != 0) {
error = ERESTART;
goto fail2;
- } else if (__predict_false(p1->p_pgrp != pg || sig_intr() != 0)) {
+ }
+ if (__predict_false(p1->p_pgrp != pg || sig_intr() != 0)) {
/*
* Either the process was moved to other process
* group, or there is pending signal. sx_slock_sig()
@@ -1062,8 +1078,8 @@
}
do_fork(td, fr, newproc, td2, vm2, fp_procdesc);
- sx_sunlock(&pg->pg_killsx);
- return (0);
+ error = 0;
+ goto cleanup;
fail0:
error = EAGAIN;
#ifdef MAC
@@ -1081,9 +1097,16 @@
fdrop(fp_procdesc, td);
}
atomic_add_int(&nprocs, -1);
+cleanup:
if (killsx_locked)
sx_sunlock(&pg->pg_killsx);
- pause("fork", hz / 2);
+ if (singlethreaded) {
+ PROC_LOCK(p1);
+ thread_single_end(p1, SINGLE_BOUNDARY);
+ PROC_UNLOCK(p1);
+ }
+ if (error != 0)
+ pause("fork", hz / 2);
return (error);
}
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -2158,14 +2158,18 @@
if (curproc == p && !SIGISMEMBER(curthread->td_sigmask, sig) &&
(!fast_sigblock || curthread->td_sigblock_val == 0))
return (curthread);
+
+ /* Find a non-stopped thread that does not mask the signal. */
signal_td = NULL;
FOREACH_THREAD_IN_PROC(p, td) {
if (!SIGISMEMBER(td->td_sigmask, sig) && (!fast_sigblock ||
- td != curthread || td->td_sigblock_val == 0)) {
+ td != curthread || td->td_sigblock_val == 0) &&
+ (td->td_flags & TDF_BOUNDARY) == 0) {
signal_td = td;
break;
}
}
+ /* Select random (first) thread if no better match was found. */
if (signal_td == NULL)
signal_td = FIRST_THREAD_IN_PROC(p);
return (signal_td);

File Metadata

Mime Type
text/plain
Expires
Mon, Jan 27, 6:14 PM (5 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16203451
Default Alt Text
D41128.id125092.diff (2 KB)

Event Timeline