* 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:
parent
83e28e5176
commit
c5bf9ceef6
20
ChangeLog
20
ChangeLog
@ -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
1
gc.c
@ -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();
|
||||||
|
71
signal.c
71
signal.c
@ -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
|
||||||
|
12
thread.c
12
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
|
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
5
vm.c
@ -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");
|
||||||
|
10
vm_core.h
10
vm_core.h
@ -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; \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user