signal.c: directly enqueue
* signal.c (rb_f_kill): directly enqueue an ignored signal to self, except for SIGSEGV and SIGBUS. [ruby-dev:48203] [Bug #9820] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45911 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
23fce75482
commit
77af38d0a5
@ -1,3 +1,8 @@
|
|||||||
|
Sun May 11 01:10:31 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* signal.c (rb_f_kill): directly enqueue an ignored signal to self,
|
||||||
|
except for SIGSEGV and SIGBUS. [ruby-dev:48203] [Bug #9820]
|
||||||
|
|
||||||
Sat May 10 22:37:56 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Sat May 10 22:37:56 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* dir.c (push_glob): match in UTF-8 on Mac OS X.
|
* dir.c (push_glob): match in UTF-8 on Mac OS X.
|
||||||
|
60
signal.c
60
signal.c
@ -350,6 +350,9 @@ ruby_default_signal(int sig)
|
|||||||
raise(sig);
|
raise(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int signal_ignored(int sig);
|
||||||
|
static void signal_enque(int sig);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* Process.kill(signal, pid, ...) -> fixnum
|
* Process.kill(signal, pid, ...) -> fixnum
|
||||||
@ -436,6 +439,8 @@ rb_f_kill(int argc, VALUE *argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argc <= 1) return INT2FIX(0);
|
||||||
|
|
||||||
if (sig < 0) {
|
if (sig < 0) {
|
||||||
sig = -sig;
|
sig = -sig;
|
||||||
for (i=1; i<argc; i++) {
|
for (i=1; i<argc; i++) {
|
||||||
@ -444,8 +449,36 @@ rb_f_kill(int argc, VALUE *argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
const rb_pid_t self = (GET_THREAD() == GET_VM()->main_thread) ? getpid() : -1;
|
||||||
|
int wakeup = 0;
|
||||||
|
|
||||||
for (i=1; i<argc; i++) {
|
for (i=1; i<argc; i++) {
|
||||||
ruby_kill(NUM2PIDT(argv[i]), sig);
|
rb_pid_t pid = NUM2PIDT(argv[i]);
|
||||||
|
|
||||||
|
if ((sig != 0) && (self != -1) && (pid == self)) {
|
||||||
|
/*
|
||||||
|
* When target pid is self, many caller assume signal will be
|
||||||
|
* delivered immediately and synchronously.
|
||||||
|
*/
|
||||||
|
switch (sig) {
|
||||||
|
case SIGSEGV:
|
||||||
|
#ifdef SIGBUS
|
||||||
|
case SIGBUS:
|
||||||
|
#endif
|
||||||
|
ruby_kill(pid, sig);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (signal_ignored(sig)) break;
|
||||||
|
signal_enque(sig);
|
||||||
|
wakeup = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (kill(pid, sig) < 0) {
|
||||||
|
rb_sys_fail(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (wakeup) {
|
||||||
|
rb_threadptr_check_signal(GET_VM()->main_thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rb_thread_execute_interrupts(rb_thread_current());
|
rb_thread_execute_interrupts(rb_thread_current());
|
||||||
@ -578,11 +611,32 @@ ruby_nativethread_signal(int signum, sighandler_t handler)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static RETSIGTYPE
|
static int
|
||||||
sighandler(int sig)
|
signal_ignored(int sig)
|
||||||
|
{
|
||||||
|
#ifdef POSIX_SIGNAL
|
||||||
|
struct sigaction old;
|
||||||
|
(void)VALGRIND_MAKE_MEM_DEFINED(&old, sizeof(old));
|
||||||
|
if (sigaction(sig, NULL, &old) < 0) return FALSE;
|
||||||
|
return old.sa_handler == SIG_IGN;
|
||||||
|
#else
|
||||||
|
sighandler_t old = signal(sig, SIG_DFL);
|
||||||
|
signal(sig, old);
|
||||||
|
return old == SIG_IGN;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
signal_enque(int sig)
|
||||||
{
|
{
|
||||||
ATOMIC_INC(signal_buff.cnt[sig]);
|
ATOMIC_INC(signal_buff.cnt[sig]);
|
||||||
ATOMIC_INC(signal_buff.size);
|
ATOMIC_INC(signal_buff.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static RETSIGTYPE
|
||||||
|
sighandler(int sig)
|
||||||
|
{
|
||||||
|
signal_enque(sig);
|
||||||
rb_thread_wakeup_timer_thread();
|
rb_thread_wakeup_timer_thread();
|
||||||
#if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
|
#if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
|
||||||
ruby_signal(sig, sighandler);
|
ruby_signal(sig, sighandler);
|
||||||
|
@ -276,4 +276,15 @@ EOS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
end if Process.respond_to?(:kill) and Signal.list.key?('HUP')
|
end if Process.respond_to?(:kill) and Signal.list.key?('HUP')
|
||||||
|
|
||||||
|
def test_ignored_interrupt
|
||||||
|
bug9820 = '[ruby-dev:48203] [Bug #9820]'
|
||||||
|
assert_separately(['-', bug9820], <<-'end;') # begin
|
||||||
|
bug = ARGV.shift
|
||||||
|
trap(:INT, "IGNORE")
|
||||||
|
assert_nothing_raised(SignalException, bug) do
|
||||||
|
Process.kill(:INT, $$)
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
end if Process.respond_to?(:kill)
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user