Page MenuHomeFreeBSD

D47741.id146954.diff
No OneTemporary

D47741.id146954.diff

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
@@ -365,6 +365,16 @@
SIGFILLSET(fastblock_mask);
SIG_CANTMASK(fastblock_mask);
ast_register(TDA_SIG, ASTR_UNCOND, 0, ast_sig);
+
+ /*
+ * TDA_PSELECT is for the case where the signal mask should be restored
+ * before delivering any signals so that we do not deliver any that are
+ * blocked by the normal thread mask. It is mutually exclusive with
+ * TDA_SIGSUSPEND, which should be used if we *do* want to deliver
+ * signals that are normally blocked, e.g., if it interrupted our sleep.
+ */
+ ast_register(TDA_PSELECT, ASTR_ASTF_REQUIRED | ASTR_TDP,
+ TDP_OLDMASK, ast_sigsuspend);
ast_register(TDA_SIGSUSPEND, ASTR_ASTF_REQUIRED | ASTR_TDP,
TDP_OLDMASK, ast_sigsuspend);
}
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -1049,14 +1049,26 @@
if (error != 0)
return (error);
td->td_pflags |= TDP_OLDMASK;
+ }
+ error = kern_select(td, nd, in, ou, ex, tvp, abi_nfdbits);
+ if (uset != NULL) {
/*
* Make sure that ast() is called on return to
* usermode and TDP_OLDMASK is cleared, restoring old
- * sigmask.
+ * sigmask. If we didn't get interrupted, then the caller is
+ * likely not expecting a signal to hit that should normally be
+ * blocked by its signal mask, so we restore the mask before
+ * any signals could be delivered.
*/
- ast_sched(td, TDA_SIGSUSPEND);
+ if (error == EINTR) {
+ ast_sched(td, TDA_SIGSUSPEND);
+ } else {
+ /* *select(2) should never restart. */
+ MPASS(error != ERESTART);
+ ast_sched(td, TDA_PSELECT);
+ }
}
- error = kern_select(td, nd, in, ou, ex, tvp, abi_nfdbits);
+
return (error);
}
@@ -1528,12 +1540,6 @@
if (error)
return (error);
td->td_pflags |= TDP_OLDMASK;
- /*
- * Make sure that ast() is called on return to
- * usermode and TDP_OLDMASK is cleared, restoring old
- * sigmask.
- */
- ast_sched(td, TDA_SIGSUSPEND);
}
seltdinit(td);
@@ -1556,6 +1562,22 @@
error = EINTR;
if (error == EWOULDBLOCK)
error = 0;
+
+ if (uset != NULL) {
+ /*
+ * Make sure that ast() is called on return to
+ * usermode and TDP_OLDMASK is cleared, restoring old
+ * sigmask. If we didn't get interrupted, then the caller is
+ * likely not expecting a signal to hit that should normally be
+ * blocked by its signal mask, so we restore the mask before
+ * any signals could be delivered.
+ */
+ if (error == EINTR)
+ ast_sched(td, TDA_SIGSUSPEND);
+ else
+ ast_sched(td, TDA_PSELECT);
+ }
+
return (error);
}
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -494,6 +494,7 @@
TDA_RACCT,
TDA_MOD1, /* For third party use, before signals are */
TAD_MOD2, /* processed .. */
+ TDA_PSELECT, /* For discarding temporary signal mask */
TDA_SIG,
TDA_KTRACE,
TDA_SUSPEND,

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 26, 6:08 PM (14 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26221661
Default Alt Text
D47741.id146954.diff (2 KB)

Event Timeline