diff options
| author | Daniel Eischen <deischen@FreeBSD.org> | 2003-05-24 02:29:25 +0000 |
|---|---|---|
| committer | Daniel Eischen <deischen@FreeBSD.org> | 2003-05-24 02:29:25 +0000 |
| commit | 1cb570c53190e8b569091f708781c6bf9c3126c7 (patch) | |
| tree | e99d3167d044ff37cf6b26fa4f4fe83140c8af79 /lib/libpthread/thread/thr_cancel.c | |
| parent | a224a3919d4b2260bb1d91fb7f848de673444c26 (diff) | |
Notes
Diffstat (limited to 'lib/libpthread/thread/thr_cancel.c')
| -rw-r--r-- | lib/libpthread/thread/thr_cancel.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/lib/libpthread/thread/thr_cancel.c b/lib/libpthread/thread/thr_cancel.c index 2c3ae5939429..064e422cadf8 100644 --- a/lib/libpthread/thread/thr_cancel.c +++ b/lib/libpthread/thread/thr_cancel.c @@ -19,6 +19,7 @@ int _pthread_cancel(pthread_t pthread) { struct pthread *curthread = _get_curthread(); + struct pthread *joinee = NULL; int ret; if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0)) == 0) { @@ -64,7 +65,17 @@ _pthread_cancel(pthread_t pthread) break; case PS_JOIN: + /* Disconnect the thread from the joinee: */ + joinee = pthread->join_status.thread; + pthread->join_status.thread = NULL; pthread->cancelflags |= THR_CANCELLING; + _thr_setrunnable_unlocked(pthread); + if ((joinee != NULL) && + (curthread->kseg == joinee->kseg)) { + /* Remove the joiner from the joinee. */ + joinee->joiner = NULL; + joinee = NULL; + } break; case PS_SUSPENDED: @@ -103,6 +114,15 @@ _pthread_cancel(pthread_t pthread) */ THR_SCHED_UNLOCK(curthread, pthread); _thr_ref_delete(curthread, pthread); + + if ((joinee != NULL) && + (_thr_ref_add(curthread, joinee, /* include dead */1) == 0)) { + /* Remove the joiner from the joinee. */ + THR_SCHED_LOCK(curthread, joinee); + joinee->joiner = NULL; + THR_SCHED_UNLOCK(curthread, joinee); + _thr_ref_delete(curthread, joinee); + } } return (ret); } |
