From 06439ad77f700f17b60bf9a9e125bdcec06d0699 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 (cherry picked from commit 880f84b24fb415d118fca09f506626a196199d9b) --- 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) {