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_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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

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_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);

View File

@ -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);

View File

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

View File

@ -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)

View File

@ -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)