diff --git a/pkgs/racket-test-core/tests/racket/sync.rktl b/pkgs/racket-test-core/tests/racket/sync.rktl index 51e27d4ab5..c9179e96ab 100644 --- a/pkgs/racket-test-core/tests/racket/sync.rktl +++ b/pkgs/racket-test-core/tests/racket/sync.rktl @@ -1439,6 +1439,25 @@ (try (lambda (c) (choice-evt c (alarm-evt (+ 10000 (current-inexact-milliseconds))))) 'ok-channel+alarm)) +;; ---------------------------------------- +;; Make sure that suspending a thread that's blocked on a +;; semaphore works right when the semaphore becomes available +;; before the thread is resumed + +(let () + (define s (make-semaphore)) + (define v #f) + (define t (thread + (lambda () + (set! v (sync (wrap-evt s (lambda (v) 'ok))))))) + (sync (system-idle-evt)) + (thread-suspend t) + (sync (system-idle-evt)) + (semaphore-post s) + (thread-resume t) + (void (sync t)) + (test 'ok values v)) + ;; ---------------------------------------- (report-errs) diff --git a/racket/src/racket/src/sema.c b/racket/src/racket/src/sema.c index 90e9628fc9..6e4d597d79 100644 --- a/racket/src/racket/src/sema.c +++ b/racket/src/racket/src/sema.c @@ -848,7 +848,7 @@ int scheme_wait_semas_chs(int n, Scheme_Object **o, int just_try, Syncing *synci if (ws[i]->in_line) get_outof_line(semas[i], ws[i]); } - + scheme_thread_block(0); /* ok if it returns multiple times */ scheme_current_thread->ran_some = 1; /* [but why would it return multiple times?! there must have been a reason...] */ @@ -910,8 +910,11 @@ int scheme_wait_semas_chs(int n, Scheme_Object **o, int just_try, Syncing *synci if (semas[i]->value) { if ((semas[i]->value > 0) && (!syncing || !syncing->reposts || !syncing->reposts[i])) --semas[i]->value; - if (syncing && syncing->accepts && syncing->accepts[i]) - scheme_accept_sync(syncing, i); + if (syncing) { + syncing->result = i + 1; + if (syncing->accepts && syncing->accepts[i]) + scheme_accept_sync(syncing, i); + } break; } } else if (semas[i]->so.type == scheme_never_evt_type) {