summaryrefslogtreecommitdiffstats
path: root/lib/libthr/thread
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2016-05-05 10:20:22 +0000
committerkib <kib@FreeBSD.org>2016-05-05 10:20:22 +0000
commit070c6cd670a6d4e5d1898e456dd8fa2d2220c14c (patch)
tree83a1eac216794bcb0bd207808d5ebafd25d55043 /lib/libthr/thread
parent2fab455b80c17b439af5840b372595a10dea4f4f (diff)
downloadFreeBSD-src-070c6cd670a6d4e5d1898e456dd8fa2d2220c14c.zip
FreeBSD-src-070c6cd670a6d4e5d1898e456dd8fa2d2220c14c.tar.gz
Do not leak THR_FLAGS_SUSPENDED from the previous suspend/resume
cycle. The flag currently is cleared by the resumed thread. If next suspend request comes before the thread was able to clean the flag, in which case suspender skip the thread. Instead, clear the THR_FLAGS_SUSPEND flag in resume_common(), we do not care how much code was executed in the resumed thread when the pthread_resume_*np(s) functions returned. PR: 209233 Reported by: Lawrence Esswood <le277@cam.ac.uk> MFC after: 1 week
Diffstat (limited to 'lib/libthr/thread')
-rw-r--r--lib/libthr/thread/thr_resume_np.c2
-rw-r--r--lib/libthr/thread/thr_sig.c4
2 files changed, 2 insertions, 4 deletions
diff --git a/lib/libthr/thread/thr_resume_np.c b/lib/libthr/thread/thr_resume_np.c
index d11e328..b280cb1 100644
--- a/lib/libthr/thread/thr_resume_np.c
+++ b/lib/libthr/thread/thr_resume_np.c
@@ -91,7 +91,7 @@ static void
resume_common(struct pthread *thread)
{
/* Clear the suspend flag: */
- thread->flags &= ~THR_FLAGS_NEED_SUSPEND;
+ thread->flags &= ~(THR_FLAGS_NEED_SUSPEND | THR_FLAGS_SUSPENDED);
thread->cycle++;
_thr_umtx_wake(&thread->cycle, 1, 0);
}
diff --git a/lib/libthr/thread/thr_sig.c b/lib/libthr/thread/thr_sig.c
index ce7e70b..8241539 100644
--- a/lib/libthr/thread/thr_sig.c
+++ b/lib/libthr/thread/thr_sig.c
@@ -374,8 +374,7 @@ check_suspend(struct pthread *curthread)
*/
curthread->critical_count++;
THR_UMUTEX_LOCK(curthread, &(curthread)->lock);
- while ((curthread->flags & (THR_FLAGS_NEED_SUSPEND |
- THR_FLAGS_SUSPENDED)) == THR_FLAGS_NEED_SUSPEND) {
+ while ((curthread->flags & THR_FLAGS_NEED_SUSPEND) != 0) {
curthread->cycle++;
cycle = curthread->cycle;
@@ -392,7 +391,6 @@ check_suspend(struct pthread *curthread)
THR_UMUTEX_UNLOCK(curthread, &(curthread)->lock);
_thr_umtx_wait_uint(&curthread->cycle, cycle, NULL, 0);
THR_UMUTEX_LOCK(curthread, &(curthread)->lock);
- curthread->flags &= ~THR_FLAGS_SUSPENDED;
}
THR_UMUTEX_UNLOCK(curthread, &(curthread)->lock);
curthread->critical_count--;
OpenPOWER on IntegriCloud