* 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: svn+ssh://ci.ruby-lang.org/ruby/trunk@19119 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2008-09-04 04:22:04 +00:00
parent 83e28e5176
commit c5bf9ceef6
6 changed files with 63 additions and 56 deletions

View File

@ -1,3 +1,21 @@
Thu Sep 4 13:22:02 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
* 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 <nobu@ruby-lang.org> Thu Sep 4 13:01:11 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
* io.c (struct sysopen_struct, rb_sysopen_internal, rb_sysopen): * io.c (struct sysopen_struct, rb_sysopen_internal, rb_sysopen):
@ -30946,7 +30964,7 @@ Wed May 17 17:55:26 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
* dir.c (sys_warning): should not call a vararg function * dir.c (sys_warning): should not call a vararg function
rb_sys_warning() indirectly. [ruby-core:07886] rb_sys_warning() indirectly. [ruby-core:07886]
Tue May 16 17:23:19 2006 <sinara@blade.nagaokaut.ac.jp> Tue May 16 17:23:19 2006 Shin-ichiro HARA <sinara@blade.nagaokaut.ac.jp>
* numeric.c (flo_divmod): the first element of Float#divmod should * numeric.c (flo_divmod): the first element of Float#divmod should
be an integer. [ruby-dev:28589] be an integer. [ruby-dev:28589]

1
gc.c
View File

@ -1986,7 +1986,6 @@ garbage_collect(rb_objspace_t *objspace)
rb_gc_mark_global_tbl(); rb_gc_mark_global_tbl();
mark_tbl(objspace, rb_class_tbl, 0); mark_tbl(objspace, rb_class_tbl, 0);
rb_gc_mark_trap_list();
/* mark generic instance variables for special constants */ /* mark generic instance variables for special constants */
rb_mark_generic_ivar_tbl(); rb_mark_generic_ivar_tbl();

View File

@ -405,29 +405,10 @@ rb_f_kill(int argc, VALUE *argv)
return INT2FIX(i-1); return INT2FIX(i-1);
} }
static struct { struct {
VALUE cmd; rb_atomic_t cnt[RUBY_NSIG];
int safe; rb_atomic_t size;
} trap_list[NSIG]; } signal_buff;
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; i<NSIG; i++) {
if (trap_list[i].cmd)
rb_gc_mark(trap_list[i].cmd);
}
#endif /* MACOS_UNUSE_SIGNAL */
}
#ifdef __dietlibc__ #ifdef __dietlibc__
#define sighandler_t sh_t #define sighandler_t sh_t
@ -486,10 +467,8 @@ ruby_nativethread_signal(int signum, sighandler_t handler)
static RETSIGTYPE static RETSIGTYPE
sighandler(int sig) sighandler(int sig)
{ {
rb_vm_t *vm = GET_VM(); /* fix me for Multi-VM */ ATOMIC_INC(signal_buff.cnt[sig]);
ATOMIC_INC(vm->signal_buff[sig]); ATOMIC_INC(signal_buff.size);
ATOMIC_INC(vm->buffered_signal_size);
#if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL) #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
ruby_signal(sig, sighandler); ruby_signal(sig, sighandler);
#endif #endif
@ -530,16 +509,16 @@ rb_enable_interrupt(void)
} }
int int
rb_get_next_signal(rb_vm_t *vm) rb_get_next_signal(void)
{ {
int i, sig = 0; int i, sig = 0;
for (i=1; i<RUBY_NSIG; i++) { for (i=1; i<RUBY_NSIG; i++) {
if (vm->signal_buff[i] > 0) { if (signal_buff.cnt[i] > 0) {
rb_disable_interrupt(); rb_disable_interrupt();
{ {
ATOMIC_DEC(vm->signal_buff[i]); ATOMIC_DEC(signal_buff.cnt[i]);
ATOMIC_DEC(vm->buffered_signal_size); ATOMIC_DEC(signal_buff.size);
} }
rb_enable_interrupt(); rb_enable_interrupt();
sig = i; sig = i;
@ -584,13 +563,13 @@ sigpipe(int sig)
#endif #endif
static void static void
signal_exec(VALUE cmd, int sig) signal_exec(VALUE cmd, int safe, int sig)
{ {
rb_proc_t *proc; rb_proc_t *proc;
VALUE signum = INT2FIX(sig); VALUE signum = INT2FIX(sig);
if (TYPE(cmd) == T_STRING) { 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; return;
} }
GetProcPtr(cmd, proc); GetProcPtr(cmd, proc);
@ -600,20 +579,21 @@ signal_exec(VALUE cmd, int sig)
void void
rb_trap_exit(void) rb_trap_exit(void)
{ {
#ifndef MACOS_UNUSE_SIGNAL rb_vm_t *vm = GET_VM();
if (trap_list[0].cmd) { VALUE trap_exit = vm->trap_list[0].cmd;
VALUE trap_exit = trap_list[0].cmd;
trap_list[0].cmd = 0; if (trap_exit) {
signal_exec(trap_exit, 0); vm->trap_list[0].cmd = 0;
signal_exec(trap_exit, vm->trap_list[0].safe, 0);
} }
#endif
} }
void void
rb_signal_exec(rb_thread_t *th, int sig) 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) { if (cmd == 0) {
switch (sig) { switch (sig) {
@ -646,7 +626,7 @@ rb_signal_exec(rb_thread_t *th, int sig)
rb_thread_signal_exit(th); rb_thread_signal_exit(th);
} }
else { 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; sighandler_t oldfunc, func = arg->func;
VALUE oldcmd, command = arg->cmd; VALUE oldcmd, command = arg->cmd;
int sig = arg->sig; int sig = arg->sig;
rb_vm_t *vm = GET_VM();
oldfunc = ruby_signal(sig, func); oldfunc = ruby_signal(sig, func);
oldcmd = trap_list[sig].cmd; oldcmd = vm->trap_list[sig].cmd;
switch (oldcmd) { switch (oldcmd) {
case 0: case 0:
if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE"); if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE");
@ -824,8 +805,8 @@ trap(struct trap_arg *arg)
break; break;
} }
trap_list[sig].cmd = command; vm->trap_list[sig].cmd = command;
trap_list[sig].safe = rb_safe_level(); vm->trap_list[sig].safe = rb_safe_level();
/* enable at least specified signal. */ /* enable at least specified signal. */
#if USE_TRAP_MASK #if USE_TRAP_MASK
#ifdef HAVE_SIGPROCMASK #ifdef HAVE_SIGPROCMASK
@ -992,7 +973,7 @@ init_sigchld(int sig)
if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) { if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) {
ruby_signal(sig, oldfunc); ruby_signal(sig, oldfunc);
} else { } else {
trap_list[sig].cmd = 0; GET_VM()->trap_list[sig].cmd = 0;
} }
#if USE_TRAP_MASK #if USE_TRAP_MASK

View File

@ -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 static void
timer_thread_function(void *arg) timer_thread_function(void *arg)
{ {
rb_vm_t *vm = arg; /* TODO: fix me for Multi-VM */ rb_vm_t *vm = arg; /* TODO: fix me for Multi-VM */
int sig;
/* for time slice */ /* for time slice */
RUBY_VM_SET_TIMER_INTERRUPT(vm->running_thread); RUBY_VM_SET_TIMER_INTERRUPT(vm->running_thread);
/* check signal */ /* 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; rb_thread_t *mth = vm->main_thread;
enum rb_thread_status prev_status = mth->status; enum rb_thread_status prev_status = mth->status;
mth->exec_signal = rb_get_next_signal(vm); thread_debug("main_thread: %s, sig: %d\n",
thread_debug("main_thread: %s\n", thread_status_name(prev_status)); thread_status_name(prev_status), sig);
thread_debug("buffered_signal_size: %ld, sig: %d\n", mth->exec_signal = sig;
(long)vm->buffered_signal_size, vm->main_thread->exec_signal);
if (mth->status != THREAD_KILLED) mth->status = THREAD_RUNNABLE; if (mth->status != THREAD_KILLED) mth->status = THREAD_RUNNABLE;
rb_thread_interrupt(mth); rb_thread_interrupt(mth);
mth->status = prev_status; mth->status = prev_status;

5
vm.c
View File

@ -1406,6 +1406,11 @@ rb_vm_mark(void *ptr)
} }
mark_event_hooks(vm->event_hooks); 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"); RUBY_MARK_LEAVE("vm");

View File

@ -38,6 +38,8 @@
#ifndef NSIG #ifndef NSIG
# ifdef DJGPP # ifdef DJGPP
# define NSIG SIGMAX # define NSIG SIGMAX
# elif defined MACOS_UNUSE_SIGNAL
# define NSIG 1
# else # else
# define NSIG (_SIGMAX + 1) /* For QNX */ # define NSIG (_SIGMAX + 1) /* For QNX */
# endif # endif
@ -323,8 +325,10 @@ struct rb_vm_struct
struct st_table *loading_table; struct st_table *loading_table;
/* signal */ /* signal */
int signal_buff[RUBY_NSIG]; struct {
int buffered_signal_size; VALUE cmd;
int safe;
} trap_list[RUBY_NSIG];
/* hook */ /* hook */
rb_event_hook_t *event_hooks; 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_VM() ruby_current_vm
#define GET_THREAD() ruby_current_thread #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 { \ #define rb_thread_set_current(th) do { \
rb_thread_set_current_raw(th); \ rb_thread_set_current_raw(th); \
th->vm->running_thread = th; \ th->vm->running_thread = th; \