Bug #4765 » fix-signalmask.patch
| 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);
|
||