This is an automated email from the git hooks/post-receive script. civodul pushed a commit to branch main in repository guile.
The following commit(s) were added to refs/heads/main by this push: new 455ee49f5 Fix asymetric mutex locking when joining thread. 455ee49f5 is described below commit 455ee49f5573baa1bc5237a8d49083ce588a13ee Author: Olivier Dion <olivier.d...@polymtl.ca> AuthorDate: Thu Jan 25 16:45:47 2024 -0500 Fix asymetric mutex locking when joining thread. If `join-thread' timeout, the thread mutex is not unlocked, resulting in deadlock to the next call to it or deadlock of the thread itself when it terminates. Thus, always unlock the mutex. Fixes <https://bugs.gnu.org/55356>. * module/ice-9/threads.scm (join-thread): Always unlock thread mutex. * test-suite/tests/threads.test (join-thread): New test to ensure the mutex is released. * NEWS: Update. Signed-off-by: Ludovic Courtès <l...@gnu.org> --- NEWS | 2 ++ module/ice-9/threads.scm | 4 +++- test-suite/tests/threads.test | 16 +++++++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 57fc6f776..0bfbd1dd8 100644 --- a/NEWS +++ b/NEWS @@ -37,6 +37,8 @@ the compiler reports it as "possibly unused". (<https://bugs.gnu.org/64666>) ** Avoid module resolution in 'call-with-new-thread', which could deadlock (<https://bugs.gnu.org/62691>) +** Fix deadlock in 'join-thread' when timeout is hit + (<https://bugs.gnu.org/55356>) ** 'read-u8' in (scheme base) now defaults to (current-input-port) (<https://bugs.gnu.org/62690>) ** Hashing of UTF-8 symbols with non-ASCII characters avoids corruption diff --git a/module/ice-9/threads.scm b/module/ice-9/threads.scm index 048d8b085..a1e43b9fa 100644 --- a/module/ice-9/threads.scm +++ b/module/ice-9/threads.scm @@ -204,7 +204,9 @@ terminates, unless the target @var{thread} has already terminated." (wait-condition-variable cv mutex timeout) (wait-condition-variable cv mutex)) (lp)) - (else timeoutval)))))) + (else + (unlock-mutex mutex) + timeoutval)))))) (define* (try-mutex mutex) "Try to lock @var{mutex}. If the mutex is already locked, return diff --git a/test-suite/tests/threads.test b/test-suite/tests/threads.test index efdf36db2..fa89deeb2 100644 --- a/test-suite/tests/threads.test +++ b/test-suite/tests/threads.test @@ -332,7 +332,21 @@ (sleep 2) (system-async-mark aproc) (join-thread other-thread))) - #t)) + #t) + + (pass-if "do not throw exception if trying to join after timeout" + (let ((other-thread (begin-thread (pause)))) + (dynamic-wind + (const #f) + (lambda () + (join-thread other-thread 1) + ;; Up to 3.0.9, this second call would throw: "mutex + ;; already locked by thread". + ;; See <https://bugs.gnu.org/55356>. + (join-thread other-thread 1) + #t) + (lambda () + (cancel-thread other-thread)))))) ;; ;; thread cancellation