fix bug in scheduler

When a thread that is blocked on a set of semaphores and channels
is suspended and resumed after one of the events becomes ready,
and if the event has a wrapper function, then the wrapper was
not applied and the event selection was not reported correctly.

Thanks to Philip McGrath for reporting the problem.
This commit is contained in:
Matthew Flatt 2016-11-14 08:20:35 -07:00
parent 3b9354f16b
commit 115dec6fd9
2 changed files with 25 additions and 3 deletions

View File

@ -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)

View File

@ -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) {