From 880f84b24fb415d118fca09f506626a196199d9b Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Thu, 26 Jul 2012 08:40:43 -0600 Subject: [PATCH] fix bug in `sync' When `guard-evt' or `nack-guard-evt' is used, `sync' didn't account for the possibility that a channel or semaphore action might complete during the call to the guard, in which case it might fail to select the event that has already completed. Merge to v5.3 --- src/racket/src/thread.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/racket/src/thread.c b/src/racket/src/thread.c index 7ea82100d6..8313dc2f4b 100644 --- a/src/racket/src/thread.c +++ b/src/racket/src/thread.c @@ -6136,6 +6136,13 @@ static int syncing_ready(Scheme_Object *s, Scheme_Schedule_Info *sinfo) sleep_end = r_sinfo.sleep_end; + /* Calling a guard can allow thread swap, which might choose a + semaphore or a channel, so check for a result: */ + if (syncing->result) { + result = 1; + goto set_sleep_end_and_return; + } + if ((i > r_sinfo.w_i) && sinfo->false_positive_ok) { /* There was a redirection. Assert: !yep. Give up if we've chained too much. */ @@ -6181,6 +6188,9 @@ static int syncing_ready(Scheme_Object *s, Scheme_Schedule_Info *sinfo) set_sync_target(syncing, i, sema, o, NULL, repost, 1, NULL); j--; /* try again with this sema */ } + + if (syncing->result) + scheme_signal_error("internal error: sync result set unexpectedly"); } if (syncing->timeout >= 0.0) {