Permalink
Browse files

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
  • Loading branch information...
1 parent 70ef4e6 commit 880f84b24fb415d118fca09f506626a196199d9b @mflatt mflatt committed Jul 26, 2012
Showing with 10 additions and 0 deletions.
  1. +10 −0 src/racket/src/thread.c
View
@@ -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) {

0 comments on commit 880f84b

Please sign in to comment.