From de91f81fa170e8dabcb4c158c9ab8fcc07a78405 Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 4 Sep 2008 04:22:04 +0000 Subject: * vm_core.h (struct rb_vm_struct): replaced signal staff with trap staff. * signal.c (signal_buff): per process resouce now. * signal.c (trap_list): moved to VM. * signal.c (rb_get_next_signal): reverted. * signal.c (rb_trap_exit): trap_pending_list was no longer used. * thread.c (timer_thread_function): delivers buffered per-process signals to each VMs. * vm.c (rb_vm_mark): marks trap_list. git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@19119 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 20 +++++++++++++++++- gc.c | 1 - signal.c | 71 +++++++++++++++++++++++---------------------------------------- thread.c | 12 +++++------ vm.c | 5 +++++ vm_core.h | 10 ++++++--- 6 files changed, 63 insertions(+), 56 deletions(-) diff --git a/ChangeLog b/ChangeLog index 226719f0d..f30b43bf1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +Thu Sep 4 13:22:02 2008 Nobuyoshi Nakada + + * vm_core.h (struct rb_vm_struct): replaced signal staff with trap + staff. + + * signal.c (signal_buff): per process resouce now. + + * signal.c (trap_list): moved to VM. + + * signal.c (rb_get_next_signal): reverted. + + * signal.c (rb_trap_exit): trap_pending_list was no longer used. + + * thread.c (timer_thread_function): delivers buffered per-process + signals to each VMs. + + * vm.c (rb_vm_mark): marks trap_list. + Thu Sep 4 13:01:11 2008 Nobuyoshi Nakada * io.c (struct sysopen_struct, rb_sysopen_internal, rb_sysopen): @@ -30946,7 +30964,7 @@ Wed May 17 17:55:26 2006 Yukihiro Matsumoto * dir.c (sys_warning): should not call a vararg function rb_sys_warning() indirectly. [ruby-core:07886] -Tue May 16 17:23:19 2006 +Tue May 16 17:23:19 2006 Shin-ichiro HARA * numeric.c (flo_divmod): the first element of Float#divmod should be an integer. [ruby-dev:28589] diff --git a/gc.c b/gc.c index f75663b94..c7d458af9 100644 --- a/gc.c +++ b/gc.c @@ -1986,7 +1986,6 @@ garbage_collect(rb_objspace_t *objspace) rb_gc_mark_global_tbl(); mark_tbl(objspace, rb_class_tbl, 0); - rb_gc_mark_trap_list(); /* mark generic instance variables for special constants */ rb_mark_generic_ivar_tbl(); diff --git a/signal.c b/signal.c index 35c31ba50..728fd2d65 100644 --- a/signal.c +++ b/signal.c @@ -405,29 +405,10 @@ rb_f_kill(int argc, VALUE *argv) return INT2FIX(i-1); } -static struct { - VALUE cmd; - int safe; -} trap_list[NSIG]; - -VALUE -rb_get_trap_cmd(int sig) -{ - return trap_list[sig].cmd; -} - -void -rb_gc_mark_trap_list(void) -{ -#ifndef MACOS_UNUSE_SIGNAL - int i; - - for (i=0; isignal_buff[sig]); - ATOMIC_INC(vm->buffered_signal_size); - + ATOMIC_INC(signal_buff.cnt[sig]); + ATOMIC_INC(signal_buff.size); #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL) ruby_signal(sig, sighandler); #endif @@ -530,16 +509,16 @@ rb_enable_interrupt(void) } int -rb_get_next_signal(rb_vm_t *vm) +rb_get_next_signal(void) { int i, sig = 0; for (i=1; isignal_buff[i] > 0) { + if (signal_buff.cnt[i] > 0) { rb_disable_interrupt(); { - ATOMIC_DEC(vm->signal_buff[i]); - ATOMIC_DEC(vm->buffered_signal_size); + ATOMIC_DEC(signal_buff.cnt[i]); + ATOMIC_DEC(signal_buff.size); } rb_enable_interrupt(); sig = i; @@ -584,13 +563,13 @@ sigpipe(int sig) #endif static void -signal_exec(VALUE cmd, int sig) +signal_exec(VALUE cmd, int safe, int sig) { rb_proc_t *proc; VALUE signum = INT2FIX(sig); if (TYPE(cmd) == T_STRING) { - rb_eval_cmd(cmd, rb_ary_new3(1, signum), trap_list[sig].safe); + rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe); return; } GetProcPtr(cmd, proc); @@ -600,20 +579,21 @@ signal_exec(VALUE cmd, int sig) void rb_trap_exit(void) { -#ifndef MACOS_UNUSE_SIGNAL - if (trap_list[0].cmd) { - VALUE trap_exit = trap_list[0].cmd; + rb_vm_t *vm = GET_VM(); + VALUE trap_exit = vm->trap_list[0].cmd; - trap_list[0].cmd = 0; - signal_exec(trap_exit, 0); + if (trap_exit) { + vm->trap_list[0].cmd = 0; + signal_exec(trap_exit, vm->trap_list[0].safe, 0); } -#endif } void rb_signal_exec(rb_thread_t *th, int sig) { - VALUE cmd = rb_get_trap_cmd(sig); + rb_vm_t *vm = GET_VM(); + VALUE cmd = vm->trap_list[sig].cmd; + int safe = vm->trap_list[sig].safe; if (cmd == 0) { switch (sig) { @@ -646,7 +626,7 @@ rb_signal_exec(rb_thread_t *th, int sig) rb_thread_signal_exit(th); } else { - signal_exec(cmd, sig); + signal_exec(cmd, safe, sig); } } @@ -810,9 +790,10 @@ trap(struct trap_arg *arg) sighandler_t oldfunc, func = arg->func; VALUE oldcmd, command = arg->cmd; int sig = arg->sig; + rb_vm_t *vm = GET_VM(); oldfunc = ruby_signal(sig, func); - oldcmd = trap_list[sig].cmd; + oldcmd = vm->trap_list[sig].cmd; switch (oldcmd) { case 0: if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE"); @@ -824,8 +805,8 @@ trap(struct trap_arg *arg) break; } - trap_list[sig].cmd = command; - trap_list[sig].safe = rb_safe_level(); + vm->trap_list[sig].cmd = command; + vm->trap_list[sig].safe = rb_safe_level(); /* enable at least specified signal. */ #if USE_TRAP_MASK #ifdef HAVE_SIGPROCMASK @@ -992,7 +973,7 @@ init_sigchld(int sig) if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) { ruby_signal(sig, oldfunc); } else { - trap_list[sig].cmd = 0; + GET_VM()->trap_list[sig].cmd = 0; } #if USE_TRAP_MASK diff --git a/thread.c b/thread.c index ce93b1d46..268b58e7c 100644 --- a/thread.c +++ b/thread.c @@ -2226,24 +2226,24 @@ rb_gc_save_machine_context(rb_thread_t *th) * */ -int rb_get_next_signal(rb_vm_t *vm); +int rb_get_next_signal(void); static void timer_thread_function(void *arg) { rb_vm_t *vm = arg; /* TODO: fix me for Multi-VM */ + int sig; /* for time slice */ RUBY_VM_SET_TIMER_INTERRUPT(vm->running_thread); /* check signal */ - if (vm->buffered_signal_size && vm->main_thread->exec_signal == 0) { + if ((sig = rb_get_next_signal()) > 0) { rb_thread_t *mth = vm->main_thread; enum rb_thread_status prev_status = mth->status; - mth->exec_signal = rb_get_next_signal(vm); - thread_debug("main_thread: %s\n", thread_status_name(prev_status)); - thread_debug("buffered_signal_size: %ld, sig: %d\n", - (long)vm->buffered_signal_size, vm->main_thread->exec_signal); + thread_debug("main_thread: %s, sig: %d\n", + thread_status_name(prev_status), sig); + mth->exec_signal = sig; if (mth->status != THREAD_KILLED) mth->status = THREAD_RUNNABLE; rb_thread_interrupt(mth); mth->status = prev_status; diff --git a/vm.c b/vm.c index 730d89c6b..b1f22e7d8 100644 --- a/vm.c +++ b/vm.c @@ -1406,6 +1406,11 @@ rb_vm_mark(void *ptr) } mark_event_hooks(vm->event_hooks); + + for (i = 0; i < RUBY_NSIG; i++) { + if (vm->trap_list[i].cmd) + rb_gc_mark(vm->trap_list[i].cmd); + } } RUBY_MARK_LEAVE("vm"); diff --git a/vm_core.h b/vm_core.h index 3c4dec076..130f6c2b2 100644 --- a/vm_core.h +++ b/vm_core.h @@ -38,6 +38,8 @@ #ifndef NSIG # ifdef DJGPP # define NSIG SIGMAX +# elif defined MACOS_UNUSE_SIGNAL +# define NSIG 1 # else # define NSIG (_SIGMAX + 1) /* For QNX */ # endif @@ -323,8 +325,10 @@ struct rb_vm_struct struct st_table *loading_table; /* signal */ - int signal_buff[RUBY_NSIG]; - int buffered_signal_size; + struct { + VALUE cmd; + int safe; + } trap_list[RUBY_NSIG]; /* hook */ rb_event_hook_t *event_hooks; @@ -682,7 +686,7 @@ extern rb_vm_t *ruby_current_vm; #define GET_VM() ruby_current_vm #define GET_THREAD() ruby_current_thread -#define rb_thread_set_current_raw(th) (ruby_current_thread = th) +#define rb_thread_set_current_raw(th) (void)(ruby_current_thread = (th)) #define rb_thread_set_current(th) do { \ rb_thread_set_current_raw(th); \ th->vm->running_thread = th; \ -- cgit