From 36d437a74764c31e145fc9de5092c580aad0a5b8 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 12 Oct 2010 20:49:14 -0600 Subject: [PATCH] fix SIGINT handling thread dependency --- src/racket/include/mzwin.def | 2 ++ src/racket/include/mzwin3m.def | 2 ++ src/racket/include/racket.exp | 2 ++ src/racket/include/racket3m.exp | 2 ++ src/racket/main.c | 11 ++++++++--- src/racket/src/schemef.h | 2 ++ src/racket/src/schemex.h | 2 ++ src/racket/src/schemex.inc | 2 ++ src/racket/src/schemexm.h | 2 ++ src/racket/src/thread.c | 16 ++++++++++++++-- 10 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/racket/include/mzwin.def b/src/racket/include/mzwin.def index e7cf48a25b..0513b6edd2 100644 --- a/src/racket/include/mzwin.def +++ b/src/racket/include/mzwin.def @@ -35,6 +35,8 @@ EXPORTS scheme_kill_thread scheme_break_thread scheme_break_main_thread + scheme_break_main_thread_at + scheme_get_main_thread_break_handle scheme_set_break_main_target scheme_thread_block scheme_thread_block_enable_break diff --git a/src/racket/include/mzwin3m.def b/src/racket/include/mzwin3m.def index 9bf3983e38..e3e83804f3 100644 --- a/src/racket/include/mzwin3m.def +++ b/src/racket/include/mzwin3m.def @@ -35,6 +35,8 @@ EXPORTS scheme_kill_thread scheme_break_thread scheme_break_main_thread + scheme_break_main_thread_at + scheme_get_main_thread_break_handle scheme_set_break_main_target scheme_thread_block scheme_thread_block_enable_break diff --git a/src/racket/include/racket.exp b/src/racket/include/racket.exp index 007918dfff..217d796153 100644 --- a/src/racket/include/racket.exp +++ b/src/racket/include/racket.exp @@ -33,6 +33,8 @@ scheme_thread_w_details scheme_kill_thread scheme_break_thread scheme_break_main_thread +scheme_break_main_thread_at +scheme_get_main_thread_break_handle scheme_set_break_main_target scheme_thread_block scheme_thread_block_enable_break diff --git a/src/racket/include/racket3m.exp b/src/racket/include/racket3m.exp index 1cfeca2f42..9900400399 100644 --- a/src/racket/include/racket3m.exp +++ b/src/racket/include/racket3m.exp @@ -33,6 +33,8 @@ scheme_thread_w_details scheme_kill_thread scheme_break_thread scheme_break_main_thread +scheme_break_main_thread_at +scheme_get_main_thread_break_handle scheme_set_break_main_target scheme_thread_block scheme_thread_block_enable_break diff --git a/src/racket/main.c b/src/racket/main.c index cdf056e6ad..523d0be98c 100644 --- a/src/racket/main.c +++ b/src/racket/main.c @@ -172,10 +172,13 @@ extern Scheme_Object *scheme_initialize(Scheme_Env *env); #ifndef NO_USER_BREAK_HANDLER +static void *break_handle; +static void *signal_handle; + static void user_break_hit(int ignore) { - scheme_break_main_thread(); - scheme_signal_received(); + scheme_break_main_thread_at(break_handle); + scheme_signal_received_at(signal_handle); # ifdef SIGSET_NEEDS_REINSTALL MZ_SIGSET(SIGINT, user_break_hit); @@ -314,7 +317,9 @@ static int main_after_stack(void *data) #endif #ifndef NO_USER_BREAK_HANDLER - MZ_SIGSET(SIGINT, user_break_hit); + break_handle = scheme_get_main_thread_break_handle(); + signal_handle = scheme_get_signal_handle(); + MZ_SIGSET(SIGINT, user_break_hit); #endif rval = run_from_cmd_line(argc, argv, scheme_basic_env, cont_run); diff --git a/src/racket/src/schemef.h b/src/racket/src/schemef.h index 4dc2e3f1e4..ff4709b8d6 100644 --- a/src/racket/src/schemef.h +++ b/src/racket/src/schemef.h @@ -99,6 +99,8 @@ MZ_EXTERN Scheme_Object *scheme_thread_w_details(Scheme_Object *thunk, MZ_EXTERN void scheme_kill_thread(Scheme_Thread *p); MZ_EXTERN void scheme_break_thread(Scheme_Thread *p); MZ_EXTERN void scheme_break_main_thread(); +MZ_EXTERN void scheme_break_main_thread_at(void *); +MZ_EXTERN void *scheme_get_main_thread_break_handle(); MZ_EXTERN void scheme_set_break_main_target(Scheme_Thread *p); MZ_EXTERN void scheme_thread_block(float sleep_time); diff --git a/src/racket/src/schemex.h b/src/racket/src/schemex.h index d23416ffbf..bdc89f06b0 100644 --- a/src/racket/src/schemex.h +++ b/src/racket/src/schemex.h @@ -81,6 +81,8 @@ Scheme_Object *(*scheme_thread_w_details)(Scheme_Object *thunk, void (*scheme_kill_thread)(Scheme_Thread *p); void (*scheme_break_thread)(Scheme_Thread *p); void (*scheme_break_main_thread)(); +void (*scheme_break_main_thread_at)(void *); +void *(*scheme_get_main_thread_break_handle)(); void (*scheme_set_break_main_target)(Scheme_Thread *p); void (*scheme_thread_block)(float sleep_time); void (*scheme_thread_block_enable_break)(float sleep_time, int enable); diff --git a/src/racket/src/schemex.inc b/src/racket/src/schemex.inc index 5b08be1366..9865b62e37 100644 --- a/src/racket/src/schemex.inc +++ b/src/racket/src/schemex.inc @@ -41,6 +41,8 @@ scheme_extension_table->scheme_kill_thread = scheme_kill_thread; scheme_extension_table->scheme_break_thread = scheme_break_thread; scheme_extension_table->scheme_break_main_thread = scheme_break_main_thread; + scheme_extension_table->scheme_break_main_thread_at = scheme_break_main_thread_at; + scheme_extension_table->scheme_get_main_thread_break_handle = scheme_get_main_thread_break_handle; scheme_extension_table->scheme_set_break_main_target = scheme_set_break_main_target; scheme_extension_table->scheme_thread_block = scheme_thread_block; scheme_extension_table->scheme_thread_block_enable_break = scheme_thread_block_enable_break; diff --git a/src/racket/src/schemexm.h b/src/racket/src/schemexm.h index 0ad9fe40cd..50b5236aa9 100644 --- a/src/racket/src/schemexm.h +++ b/src/racket/src/schemexm.h @@ -41,6 +41,8 @@ #define scheme_kill_thread (scheme_extension_table->scheme_kill_thread) #define scheme_break_thread (scheme_extension_table->scheme_break_thread) #define scheme_break_main_thread (scheme_extension_table->scheme_break_main_thread) +#define scheme_break_main_thread_at (scheme_extension_table->scheme_break_main_thread_at) +#define scheme_get_main_thread_break_handle (scheme_extension_table->scheme_get_main_thread_break_handle) #define scheme_set_break_main_target (scheme_extension_table->scheme_set_break_main_target) #define scheme_thread_block (scheme_extension_table->scheme_thread_block) #define scheme_thread_block_enable_break (scheme_extension_table->scheme_thread_block_enable_break) diff --git a/src/racket/src/thread.c b/src/racket/src/thread.c index 93bad54849..e678d9aafe 100644 --- a/src/racket/src/thread.c +++ b/src/racket/src/thread.c @@ -3981,14 +3981,26 @@ static void exit_or_escape(Scheme_Thread *p) select_thread(); } -void scheme_break_main_thread() +void scheme_break_main_thread_at(void *p) /* This function can be called from an interrupt handler. On some platforms, it will even be called from multiple OS threads. In the case of multiple threads, there's a tiny chance that a single Ctl-C will trigger multiple break exceptions. */ { - delayed_break_ready = 1; + *(volatile short *)p = 1; +} + +void scheme_break_main_thread() +/* Calling this function from an arbitary + thread is dangerous when therad locals are enabled. */ +{ + scheme_break_main_thread_at((void *)&delayed_break_ready); +} + +void *scheme_get_main_thread_break_handle() +{ + return (void *)&delayed_break_ready; } void scheme_set_break_main_target(Scheme_Thread *p)