Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137776757
D47741.id146954.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D47741.id146954.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D47741: kern: restore signal mask before ast() for pselect/ppoll
Attached
Detach File
Event Timeline
Log In to Comment