From 769ad3e98aa7f990e6cc4b1ef132287b49e3fe9c Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 22 Mar 2009 16:24:50 +0000 Subject: [PATCH] fix bug in sync/enable-break where a channel recv could be accepted during the raise of a break exn; also, post NACKs before raising exn svn: r14218 --- src/mzscheme/src/sema.c | 3 +++ src/mzscheme/src/thread.c | 10 ++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/mzscheme/src/sema.c b/src/mzscheme/src/sema.c index 4980063a15..0e927e49a8 100644 --- a/src/mzscheme/src/sema.c +++ b/src/mzscheme/src/sema.c @@ -387,6 +387,7 @@ static int out_of_line(Scheme_Object *a) } static void get_into_line(Scheme_Sema *sema, Scheme_Channel_Syncer *w) + /* Can be called multiple times. */ { Scheme_Channel_Syncer *last, *first; @@ -430,6 +431,8 @@ static void get_outof_line(Scheme_Sema *sema, Scheme_Channel_Syncer *w) { Scheme_Channel_Syncer *last, *first; + if (!w->in_line) + return; w->in_line = 0; if (SAME_TYPE(SCHEME_TYPE(sema), scheme_never_evt_type)) { diff --git a/src/mzscheme/src/thread.c b/src/mzscheme/src/thread.c index 232d6be8cd..0561f29992 100644 --- a/src/mzscheme/src/thread.c +++ b/src/mzscheme/src/thread.c @@ -363,6 +363,7 @@ static Scheme_Object *will_executor_go(int argc, Scheme_Object *args[]); static Scheme_Object *will_executor_sema(Scheme_Object *w, int *repost); static Scheme_Object *check_break_now(int argc, Scheme_Object *args[]); +static int syncing_ready(Scheme_Object *s, Scheme_Schedule_Info *sinfo); static void make_initial_config(Scheme_Thread *p); @@ -3772,6 +3773,11 @@ static void raise_break(Scheme_Thread *p) p->external_break = 0; + if (p->blocker && (p->block_check == syncing_ready)) { + /* Get out of lines for channels, etc., before calling a break exn handler. */ + scheme_post_syncing_nacks((Syncing *)p->blocker); + } + block_descriptor = p->block_descriptor; blocker = p->blocker; block_check = p->block_check; @@ -5677,7 +5683,7 @@ Scheme_Object *scheme_make_evt_set(int argc, Scheme_Object **argv) } void scheme_post_syncing_nacks(Syncing *syncing) - /* Also removes channel-syncers */ + /* Also removes channel-syncers. Can be called multiple times. */ { int i, c; Scheme_Object *l; @@ -5792,7 +5798,7 @@ static Scheme_Object *do_sync(const char *name, int argc, Scheme_Object *argv[], timeout = 0.0; /* means "no timeout" to block_until */ if (with_break) { - /* Suspended breaks when something is selected: */ + /* Suspended breaks when something is selected. */ syncing->disable_break = scheme_current_thread; }