1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-03 09:00:21 +00:00

Check unhandled signals before thread marks itself as DEAD,

this reduces chances of signal losting problem found by
Peter Holm <peter@holm.cc>
This commit is contained in:
David Xu 2004-10-23 23:37:54 +00:00
parent b4f9f84b96
commit fca6ccde6e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=136847
2 changed files with 28 additions and 2 deletions

View File

@ -105,7 +105,20 @@ _pthread_exit(void *status)
THR_SCHED_LOCK(curthread, curthread);
curthread->flags |= THR_FLAGS_EXITING;
THR_SCHED_UNLOCK(curthread, curthread);
/*
* To avoid signal-lost problem, if signals had already been
* delivered to us, handle it. we have already set EXITING flag
* so no new signals should be delivered to us.
* XXX this is not enough if signal was delivered just before
* thread called sigprocmask and masked it! in this case, we
* might have to re-post the signal by kill() if the signal
* is targeting process (not for a specified thread).
* Kernel has same signal-lost problem, a signal may be delivered
* to a thread which is on the way to call sigprocmask or thr_exit()!
*/
if (curthread->check_pending)
_thr_sig_check_pending(curthread);
/* Save the return value: */
curthread->ret = status;
while (curthread->cleanup != NULL) {

View File

@ -105,7 +105,20 @@ _pthread_exit(void *status)
THR_SCHED_LOCK(curthread, curthread);
curthread->flags |= THR_FLAGS_EXITING;
THR_SCHED_UNLOCK(curthread, curthread);
/*
* To avoid signal-lost problem, if signals had already been
* delivered to us, handle it. we have already set EXITING flag
* so no new signals should be delivered to us.
* XXX this is not enough if signal was delivered just before
* thread called sigprocmask and masked it! in this case, we
* might have to re-post the signal by kill() if the signal
* is targeting process (not for a specified thread).
* Kernel has same signal-lost problem, a signal may be delivered
* to a thread which is on the way to call sigprocmask or thr_exit()!
*/
if (curthread->check_pending)
_thr_sig_check_pending(curthread);
/* Save the return value: */
curthread->ret = status;
while (curthread->cleanup != NULL) {