diff options
author | kib <kib@FreeBSD.org> | 2016-05-05 10:20:22 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2016-05-05 10:20:22 +0000 |
commit | 070c6cd670a6d4e5d1898e456dd8fa2d2220c14c (patch) | |
tree | 83a1eac216794bcb0bd207808d5ebafd25d55043 /lib/libthr/thread | |
parent | 2fab455b80c17b439af5840b372595a10dea4f4f (diff) | |
download | FreeBSD-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.c | 2 | ||||
-rw-r--r-- | lib/libthr/thread/thr_sig.c | 4 |
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--; |