fix SIGINT handling thread dependency

This commit is contained in:
Matthew Flatt 2010-10-12 20:49:14 -06:00
parent df62ca47e9
commit 36d437a747
10 changed files with 38 additions and 5 deletions

View File

@ -35,6 +35,8 @@ EXPORTS
scheme_kill_thread scheme_kill_thread
scheme_break_thread scheme_break_thread
scheme_break_main_thread scheme_break_main_thread
scheme_break_main_thread_at
scheme_get_main_thread_break_handle
scheme_set_break_main_target scheme_set_break_main_target
scheme_thread_block scheme_thread_block
scheme_thread_block_enable_break scheme_thread_block_enable_break

View File

@ -35,6 +35,8 @@ EXPORTS
scheme_kill_thread scheme_kill_thread
scheme_break_thread scheme_break_thread
scheme_break_main_thread scheme_break_main_thread
scheme_break_main_thread_at
scheme_get_main_thread_break_handle
scheme_set_break_main_target scheme_set_break_main_target
scheme_thread_block scheme_thread_block
scheme_thread_block_enable_break scheme_thread_block_enable_break

View File

@ -33,6 +33,8 @@ scheme_thread_w_details
scheme_kill_thread scheme_kill_thread
scheme_break_thread scheme_break_thread
scheme_break_main_thread scheme_break_main_thread
scheme_break_main_thread_at
scheme_get_main_thread_break_handle
scheme_set_break_main_target scheme_set_break_main_target
scheme_thread_block scheme_thread_block
scheme_thread_block_enable_break scheme_thread_block_enable_break

View File

@ -33,6 +33,8 @@ scheme_thread_w_details
scheme_kill_thread scheme_kill_thread
scheme_break_thread scheme_break_thread
scheme_break_main_thread scheme_break_main_thread
scheme_break_main_thread_at
scheme_get_main_thread_break_handle
scheme_set_break_main_target scheme_set_break_main_target
scheme_thread_block scheme_thread_block
scheme_thread_block_enable_break scheme_thread_block_enable_break

View File

@ -172,10 +172,13 @@ extern Scheme_Object *scheme_initialize(Scheme_Env *env);
#ifndef NO_USER_BREAK_HANDLER #ifndef NO_USER_BREAK_HANDLER
static void *break_handle;
static void *signal_handle;
static void user_break_hit(int ignore) static void user_break_hit(int ignore)
{ {
scheme_break_main_thread(); scheme_break_main_thread_at(break_handle);
scheme_signal_received(); scheme_signal_received_at(signal_handle);
# ifdef SIGSET_NEEDS_REINSTALL # ifdef SIGSET_NEEDS_REINSTALL
MZ_SIGSET(SIGINT, user_break_hit); MZ_SIGSET(SIGINT, user_break_hit);
@ -314,7 +317,9 @@ static int main_after_stack(void *data)
#endif #endif
#ifndef NO_USER_BREAK_HANDLER #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 #endif
rval = run_from_cmd_line(argc, argv, scheme_basic_env, cont_run); rval = run_from_cmd_line(argc, argv, scheme_basic_env, cont_run);

View File

@ -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_kill_thread(Scheme_Thread *p);
MZ_EXTERN void scheme_break_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();
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_set_break_main_target(Scheme_Thread *p);
MZ_EXTERN void scheme_thread_block(float sleep_time); MZ_EXTERN void scheme_thread_block(float sleep_time);

View File

@ -81,6 +81,8 @@ Scheme_Object *(*scheme_thread_w_details)(Scheme_Object *thunk,
void (*scheme_kill_thread)(Scheme_Thread *p); void (*scheme_kill_thread)(Scheme_Thread *p);
void (*scheme_break_thread)(Scheme_Thread *p); void (*scheme_break_thread)(Scheme_Thread *p);
void (*scheme_break_main_thread)(); 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_set_break_main_target)(Scheme_Thread *p);
void (*scheme_thread_block)(float sleep_time); void (*scheme_thread_block)(float sleep_time);
void (*scheme_thread_block_enable_break)(float sleep_time, int enable); void (*scheme_thread_block_enable_break)(float sleep_time, int enable);

View File

@ -41,6 +41,8 @@
scheme_extension_table->scheme_kill_thread = scheme_kill_thread; scheme_extension_table->scheme_kill_thread = scheme_kill_thread;
scheme_extension_table->scheme_break_thread = scheme_break_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 = 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_set_break_main_target = scheme_set_break_main_target;
scheme_extension_table->scheme_thread_block = scheme_thread_block; scheme_extension_table->scheme_thread_block = scheme_thread_block;
scheme_extension_table->scheme_thread_block_enable_break = scheme_thread_block_enable_break; scheme_extension_table->scheme_thread_block_enable_break = scheme_thread_block_enable_break;

View File

@ -41,6 +41,8 @@
#define scheme_kill_thread (scheme_extension_table->scheme_kill_thread) #define scheme_kill_thread (scheme_extension_table->scheme_kill_thread)
#define scheme_break_thread (scheme_extension_table->scheme_break_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 (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_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 (scheme_extension_table->scheme_thread_block)
#define scheme_thread_block_enable_break (scheme_extension_table->scheme_thread_block_enable_break) #define scheme_thread_block_enable_break (scheme_extension_table->scheme_thread_block_enable_break)

View File

@ -3981,14 +3981,26 @@ static void exit_or_escape(Scheme_Thread *p)
select_thread(); select_thread();
} }
void scheme_break_main_thread() void scheme_break_main_thread_at(void *p)
/* This function can be called from an interrupt handler. /* This function can be called from an interrupt handler.
On some platforms, it will even be called from multiple On some platforms, it will even be called from multiple
OS threads. In the case of multiple threads, there's a OS threads. In the case of multiple threads, there's a
tiny chance that a single Ctl-C will trigger multiple tiny chance that a single Ctl-C will trigger multiple
break exceptions. */ 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) void scheme_set_break_main_target(Scheme_Thread *p)