X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Finterrupt.c;h=723952885ef581e55585a4b2d1a621b670ec2ac8;hb=c3699db2053ff3b5ac6a98d4431c3789496002d8;hp=1c9a1b52047f37057ac6e90283ae021077b1a263;hpb=c2bce3b9eb9f51fb0657af3c9023fff86ba3a51f;p=sbcl.git diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index 1c9a1b5..7239528 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -45,6 +45,8 @@ #include #include #include +#include +#include #include "runtime.h" #include "arch.h" @@ -62,6 +64,8 @@ #include "genesis/fdefn.h" #include "genesis/simple-fun.h" + + void run_deferred_handler(struct interrupt_data *data, void *v_context) ; static void store_signal_data_for_later (struct interrupt_data *data, void *handler, int signal, @@ -105,6 +109,7 @@ void sigaddset_blockable(sigset_t *s) #ifdef LISP_FEATURE_SB_THREAD sigaddset(s, SIG_STOP_FOR_GC); sigaddset(s, SIG_INTERRUPT_THREAD); + sigaddset(s, SIG_THREAD_EXIT); #endif } @@ -655,17 +660,40 @@ void arrange_return_to_lisp_function(os_context_t *context, lispobj function) } #ifdef LISP_FEATURE_SB_THREAD -void handle_rt_signal(int num, siginfo_t *info, void *v_context) +void interrupt_thread_handler(int num, siginfo_t *info, void *v_context) { os_context_t *context = (os_context_t*)arch_os_get_context(&v_context); struct thread *th=arch_os_get_current_thread(); struct interrupt_data *data= th ? th->interrupt_data : global_interrupt_data; - if(maybe_defer_handler(handle_rt_signal,data,num,info,context)){ + if(maybe_defer_handler(interrupt_thread_handler,data,num,info,context)){ return ; } arrange_return_to_lisp_function(context,info->si_value.sival_int); } + +void thread_exit_handler(int num, siginfo_t *info, void *v_context) +{ /* called when a child thread exits */ + os_context_t *context = (os_context_t*)arch_os_get_context(&v_context); + struct thread *th=arch_os_get_current_thread(); + pid_t kid; + int *status; + struct interrupt_data *data= + th ? th->interrupt_data : global_interrupt_data; + if(maybe_defer_handler(thread_exit_handler,data,num,info,context)){ + return ; + } + while(1) { + kid=waitpid(-1,&status,__WALL|WNOHANG); + if(kid<1) break; + if(WIFEXITED(status) || WIFSIGNALED(status)) { + struct thread *th=find_thread_by_pid(kid); + if(!th) continue; + funcall1(SymbolFunction(HANDLE_THREAD_EXIT),make_fixnum(kid)); + destroy_thread(th); + } + } +} #endif boolean handle_control_stack_guard_triggered(os_context_t *context,void *addr){