Project

General

Profile

Bug #4765 » fix-signalmask.patch

kosaki (Motohiro KOSAKI), 05/23/2011 01:33 AM

View differences:

eval.c
JUMP_TAG(TAG_FATAL);
}
rb_trap_restore_mask();
if (tag != TAG_FATAL) {
EXEC_EVENT_HOOK(th, RUBY_EVENT_RAISE, th->cfp->self, 0, 0);
}
eval_intern.h
void rb_thread_terminate_all(void);
VALUE rb_vm_top_self();
VALUE rb_vm_cbase(void);
void rb_trap_restore_mask(void);
#ifndef CharNext /* defined as CharNext[AW] on Windows. */
#define CharNext(p) ((p) + mblen((p), RUBY_MBCHAR_MAXSIZE))
lib/test/unit/parallel.rb
@@stop_auto_run = true
@opts = @options.dup
Signal.trap(:INT,"IGNORE")
@old_loadpath = []
begin
@stdout = increment_io(STDOUT)
process.c
* Therefore we have to kill internal threads at once. [ruby-core: 10583]
*/
#define before_exec() \
(rb_enable_interrupt(), (void)(forked_child ? 0 : (rb_thread_stop_timer_thread(), 1)))
((void)(forked_child ? 0 : (rb_thread_stop_timer_thread(), 1)))
#define after_exec() \
(rb_thread_reset_timer_thread(), rb_thread_start_timer_thread(), forked_child = 0, rb_disable_interrupt())
(rb_thread_reset_timer_thread(), rb_thread_start_timer_thread(), forked_child = 0)
#define before_fork() before_exec()
#define after_fork() (GET_THREAD()->thrown_errinfo = 0, after_exec())
......
void
rb_syswait(rb_pid_t pid)
{
static int overriding;
#ifdef SIGHUP
RETSIGTYPE (*hfunc)(int) = 0;
#endif
#ifdef SIGQUIT
RETSIGTYPE (*qfunc)(int) = 0;
#endif
RETSIGTYPE (*ifunc)(int) = 0;
int status;
int i, hooked = FALSE;
if (!overriding) {
#ifdef SIGHUP
hfunc = signal(SIGHUP, SIG_IGN);
#endif
#ifdef SIGQUIT
qfunc = signal(SIGQUIT, SIG_IGN);
#endif
ifunc = signal(SIGINT, SIG_IGN);
overriding = TRUE;
hooked = TRUE;
}
int i;
do {
i = rb_waitpid(pid, &status, 0);
} while (i == -1 && errno == EINTR);
if (hooked) {
#ifdef SIGHUP
signal(SIGHUP, hfunc);
#endif
#ifdef SIGQUIT
signal(SIGQUIT, qfunc);
#endif
signal(SIGINT, ifunc);
overriding = FALSE;
}
}
static VALUE
signal.c
void
ruby_default_signal(int sig)
{
sigset_t sigmask;
sigemptyset(&sigmask);
sigaddset(&sigmask, sig);
pthread_sigmask(SIG_UNBLOCK, &sigmask, NULL);
signal(sig, SIG_DFL);
raise(sig);
}
......
return signal_buff.size;
}
#if USE_TRAP_MASK
# ifdef HAVE_SIGPROCMASK
static sigset_t trap_last_mask;
# else
static int trap_last_mask;
# endif
#endif
#if HAVE_PTHREAD_H
#include <pthread.h>
#endif
......
}
#endif
#ifdef SIGPIPE
static RETSIGTYPE
sigpipe(int sig)
{
/* do nothing */
}
#endif
static void
signal_exec(VALUE cmd, int safe, int sig)
{
......
#endif
#ifdef SIGPIPE
case SIGPIPE:
func = sigpipe;
func = SIG_IGN;
break;
#endif
default:
......
{
/* enable interrupt */
pthread_sigmask(SIG_SETMASK, &arg->mask, NULL);
trap_last_mask = arg->mask;
return 0;
}
#endif
void
rb_trap_restore_mask(void)
{
#if USE_TRAP_MASK
pthread_sigmask(SIG_SETMASK, &trap_last_mask, NULL);
#endif
}
/*
* call-seq:
* Signal.trap( signal, command ) -> obj
......
#if USE_TRAP_MASK
sigdelset(&mask, sig);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
trap_last_mask = mask;
#endif
}
#endif
......
#endif
}
#ifdef SIGPIPE
install_sighandler(SIGPIPE, sigpipe);
install_sighandler(SIGPIPE, SIG_IGN);
#endif
#if defined(SIGCLD)
......
#elif defined(SIGCHLD)
init_sigchld(SIGCHLD);
#endif
rb_disable_interrupt();
}
thread_pthread.c
{
struct timespec timeout_10ms;
/* only timer thread recieve signal */
rb_enable_interrupt();
timeout_10ms.tv_sec = 0;
timeout_10ms.tv_nsec = 10 * 1000 * 1000;
......
static void
rb_thread_create_timer_thread(void)
{
rb_enable_interrupt();
if (!timer_thread_id) {
pthread_attr_t attr;
int err;
......
native_cond_wait(&timer_thread_cond, &timer_thread_lock);
native_mutex_unlock(&timer_thread_lock);
}
rb_disable_interrupt(); /* only timer thread recieve signal */
}
static int
vm_eval.c
RB_GC_GUARD(desc);
rb_raise(rb_eArgError, "uncaught throw %s", RSTRING_PTR(desc));
}
rb_trap_restore_mask();
th->errinfo = NEW_THROW_OBJECT(tag, 0, TAG_THROW);
JUMP_TAG(TAG_THROW);
(1-1/2)