[前][次][番号順一覧][スレッド一覧]

ruby-changes:35263

From: nagachika <ko1@a...>
Date: Tue, 2 Sep 2014 02:16:18 +0900 (JST)
Subject: [ruby-changes:35263] nagachika:r47345 (ruby_2_1): merge revision(s) r45911, r45912, r45917, r45918, r45919: [Backport #9820]

nagachika	2014-09-02 02:16:03 +0900 (Tue, 02 Sep 2014)

  New Revision: 47345

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47345

  Log:
    merge revision(s) r45911,r45912,r45917,r45918,r45919: [Backport #9820]
    
    * signal.c (rb_f_kill): directly enqueue an ignored signal to self,
      except for SIGSEGV and SIGBUS.  [ruby-dev:48203] [Bug #9820]

  Modified directories:
    branches/ruby_2_1/
  Modified files:
    branches/ruby_2_1/ChangeLog
    branches/ruby_2_1/signal.c
    branches/ruby_2_1/test/ruby/test_process.rb
    branches/ruby_2_1/test/ruby/test_signal.rb
    branches/ruby_2_1/thread.c
    branches/ruby_2_1/version.h
Index: ruby_2_1/ChangeLog
===================================================================
--- ruby_2_1/ChangeLog	(revision 47344)
+++ ruby_2_1/ChangeLog	(revision 47345)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ChangeLog#L1
+Tue Sep  2 02:08:12 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* signal.c (rb_f_kill): directly enqueue an ignored signal to self,
+	  except for SIGSEGV and SIGBUS.  [ruby-dev:48203] [Bug #9820]
+
 Sun Aug 31 01:13:21 2014  Koichi Sasada  <ko1@a...>
 
 	* gc.c: change full GC timing to keep lower memory usage.
Index: ruby_2_1/thread.c
===================================================================
--- ruby_2_1/thread.c	(revision 47344)
+++ ruby_2_1/thread.c	(revision 47345)
@@ -5320,13 +5320,12 @@ ruby_kill(rb_pid_t pid, int sig) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/thread.c#L5320
 {
     int err;
     rb_thread_t *th = GET_THREAD();
-    rb_vm_t *vm = GET_VM();
 
     /*
      * When target pid is self, many caller assume signal will be
      * delivered immediately and synchronously.
      */
-    if ((sig != 0) && (th == vm->main_thread) && (pid == getpid())) {
+    {
 	GVL_UNLOCK_BEGIN();
 	native_mutex_lock(&th->interrupt_lock);
 	err = kill(pid, sig);
@@ -5334,9 +5333,7 @@ ruby_kill(rb_pid_t pid, int sig) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/thread.c#L5333
 	native_mutex_unlock(&th->interrupt_lock);
 	GVL_UNLOCK_END();
     }
-    else {
-	err = kill(pid, sig);
-    }
-    if (err < 0)
+    if (err < 0) {
 	rb_sys_fail(0);
+    }
 }
Index: ruby_2_1/version.h
===================================================================
--- ruby_2_1/version.h	(revision 47344)
+++ ruby_2_1/version.h	(revision 47345)
@@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/version.h#L1
 #define RUBY_VERSION "2.1.2"
-#define RUBY_RELEASE_DATE "2014-08-31"
-#define RUBY_PATCHLEVEL 216
+#define RUBY_RELEASE_DATE "2014-09-02"
+#define RUBY_PATCHLEVEL 217
 
 #define RUBY_RELEASE_YEAR 2014
-#define RUBY_RELEASE_MONTH 8
-#define RUBY_RELEASE_DAY 31
+#define RUBY_RELEASE_MONTH 9
+#define RUBY_RELEASE_DAY 2
 
 #include "ruby/version.h"
 
Index: ruby_2_1/test/ruby/test_signal.rb
===================================================================
--- ruby_2_1/test/ruby/test_signal.rb	(revision 47344)
+++ ruby_2_1/test/ruby/test_signal.rb	(revision 47345)
@@ -268,4 +268,15 @@ EOS https://github.com/ruby/ruby/blob/trunk/ruby_2_1/test/ruby/test_signal.rb#L268
       }
     }
   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
Index: ruby_2_1/test/ruby/test_process.rb
===================================================================
--- ruby_2_1/test/ruby/test_process.rb	(revision 47344)
+++ ruby_2_1/test/ruby/test_process.rb	(revision 47345)
@@ -1193,6 +1193,23 @@ class TestProcess < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/ruby_2_1/test/ruby/test_process.rb#L1193
 
   def test_status_kill
     return unless Process.respond_to?(:kill)
+    return unless Signal.list.include?("KILL")
+
+    # assume the system supports signal if SIGQUIT is available
+    expected = Signal.list.include?("QUIT") ? [false, true, false, nil] : [true, false, false, true]
+
+    with_tmpchdir do
+      write_file("foo", "Process.kill(:KILL, $$); exit(42)")
+      system(RUBY, "foo")
+      s = $?
+      assert_equal(expected,
+                   [s.exited?, s.signaled?, s.stopped?, s.success?],
+                   "[s.exited?, s.signaled?, s.stopped?, s.success?]")
+    end
+  end
+
+  def test_status_quit
+    return unless Process.respond_to?(:kill)
     return unless Signal.list.include?("QUIT")
 
     with_tmpchdir do
@@ -1206,16 +1223,14 @@ class TestProcess < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/ruby_2_1/test/ruby/test_process.rb#L1223
       end
       t = Time.now
       s = $?
-      assert_equal([false, true, false],
-                   [s.exited?, s.signaled?, s.stopped?],
-                   "[s.exited?, s.signaled?, s.stopped?]")
+      assert_equal([false, true, false, nil],
+                   [s.exited?, s.signaled?, s.stopped?, s.success?],
+                   "[s.exited?, s.signaled?, s.stopped?, s.success?]")
       assert_send(
         [["#<Process::Status: pid #{ s.pid } SIGQUIT (signal #{ s.termsig })>",
           "#<Process::Status: pid #{ s.pid } SIGQUIT (signal #{ s.termsig }) (core dumped)>"],
          :include?,
          s.inspect])
-      assert_equal(false, s.exited?)
-      assert_equal(nil, s.success?)
       EnvUtil.diagnostic_reports("QUIT", RUBY, pid, t)
     end
   end
Index: ruby_2_1/signal.c
===================================================================
--- ruby_2_1/signal.c	(revision 47344)
+++ ruby_2_1/signal.c	(revision 47345)
@@ -343,6 +343,9 @@ ruby_default_signal(int sig) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/signal.c#L343
     raise(sig);
 }
 
+static int signal_ignored(int sig);
+static void signal_enque(int sig);
+
 /*
  *  call-seq:
  *     Process.kill(signal, pid, ...)    -> fixnum
@@ -429,6 +432,8 @@ rb_f_kill(int argc, VALUE *argv) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/signal.c#L432
 	break;
     }
 
+    if (argc <= 1) return INT2FIX(0);
+
     if (sig < 0) {
 	sig = -sig;
 	for (i=1; i<argc; i++) {
@@ -437,8 +442,42 @@ rb_f_kill(int argc, VALUE *argv) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/signal.c#L442
 	}
     }
     else {
+	const rb_pid_t self = (GET_THREAD() == GET_VM()->main_thread) ? getpid() : -1;
+	int wakeup = 0;
+
 	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
+#ifdef SIGKILL
+		  case SIGKILL:
+#endif
+#ifdef SIGSTOP
+		  case SIGSTOP:
+#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());
@@ -570,11 +609,32 @@ ruby_nativethread_signal(int signum, sig https://github.com/ruby/ruby/blob/trunk/ruby_2_1/signal.c#L609
 #endif
 #endif
 
-static RETSIGTYPE
-sighandler(int sig)
+static int
+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.size);
+}
+
+static RETSIGTYPE
+sighandler(int sig)
+{
+    signal_enque(sig);
     rb_thread_wakeup_timer_thread();
 #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
     ruby_signal(sig, sighandler);

Property changes on: ruby_2_1
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /trunk:r45911-45912,45917-45919


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]