bc: fix use of fsemaphores in the main thread

Fix a locking mistake in the implementation of fsemaphores.
This commit is contained in:
Matthew Flatt 2020-05-23 19:21:56 -06:00
parent eba1798c8a
commit 0473bd52f8
2 changed files with 33 additions and 3 deletions

View File

@ -0,0 +1,28 @@
#lang racket/base
(require racket/future)
;; Make sure fsemaphores can work like locks, as
;; long as every future that might hold a lock is
;; demanded by a thread (so it must continue to
;; run if it takes a lock)
(for ([N (in-range 4 20)])
(define f (make-fsemaphore 1))
(define working (box 'ok))
(define fts
(for/list ([i (in-range N)])
(define ft
(future
(lambda ()
(for ([i (in-range 5000)])
(fsemaphore-wait f)
(unless (box-cas! working 'ok 'not-ok)
(printf "FAIL\n")
(exit 1))
(unless (box-cas! working 'not-ok 'ok)
(printf "FAIL\n")
(exit 1))
(fsemaphore-post f)))))
(thread (lambda () (touch ft)))
ft))
(for-each touch fts))

View File

@ -1625,9 +1625,11 @@ Scheme_Object *scheme_fsemaphore_wait(int argc, Scheme_Object **argv)
return scheme_void;
}
do {
mzrt_mutex_unlock(sema->mut);
sema = block_until_sema_ready(sema);
mzrt_mutex_lock(sema->mut);
} while (!sema->ready);
} else {
/* On a future thread, suspend the future (to be
resumed whenever the fsema becomes ready */