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; }