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

ruby-changes:25795

From: kosaki <ko1@a...>
Date: Mon, 26 Nov 2012 17:06:06 +0900 (JST)
Subject: [ruby-changes:25795] kosaki:r37852 (trunk): * vm_core.h (rb_thread_struct): added 'in_trap' member for marking

kosaki	2012-11-26 17:05:49 +0900 (Mon, 26 Nov 2012)

  New Revision: 37852

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

  Log:
    * vm_core.h (rb_thread_struct): added 'in_trap' member for marking
      running trap handler.
    * signal.c (signal_exec): turn on in_trap when running trap.
    * thread.c (Init_Thread, thread_create_core): initialize in_trap
      when creating new threads.
    * thread.c (thread_join_m): raise ThreadError when running trap
      handler.Bug [#6416][ruby-core:44956]
    * test/ruby/test_thread.rb (test_thread_join_in_trap): new test
      for the above.

  Modified files:
    trunk/ChangeLog
    trunk/signal.c
    trunk/test/ruby/test_thread.rb
    trunk/thread.c
    trunk/vm_core.h

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 37851)
+++ ChangeLog	(revision 37852)
@@ -1,3 +1,15 @@
+Mon Nov 26 17:00:12 2012  KOSAKI Motohiro  <kosaki.motohiro@g...>
+
+	* vm_core.h (rb_thread_struct): added 'in_trap' member for marking
+	  running trap handler.
+	* signal.c (signal_exec): turn on in_trap when running trap.
+	* thread.c (Init_Thread, thread_create_core): initialize in_trap
+	  when creating new threads.
+	* thread.c (thread_join_m): raise ThreadError when running trap
+	  handler.Bug [#6416][ruby-core:44956]
+	* test/ruby/test_thread.rb (test_thread_join_in_trap): new test
+	  for the above.
+
 Mon Nov 26 16:36:13 2012  NARUSE, Yui  <naruse@r...>
 
 	* io.c (argf_each_codepoint): add missing ARGF#codepoints [Bug #7438]
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 37851)
+++ vm_core.h	(revision 37852)
@@ -584,6 +584,9 @@
     void *altstack;
 #endif
     unsigned long running_time_us;
+
+    /* 1 if running trap handler */
+    int in_trap;
 } rb_thread_t;
 
 /* iseq.c */
Index: thread.c
===================================================================
--- thread.c	(revision 37851)
+++ thread.c	(revision 37852)
@@ -567,6 +567,8 @@
     th->async_errinfo_mask_stack = rb_ary_dup(current_th->async_errinfo_mask_stack);
     RBASIC(th->async_errinfo_mask_stack)->klass = 0;
 
+    th->in_trap = 0;
+
     native_mutex_initialize(&th->interrupt_lock);
 
     /* kick thread */
@@ -790,9 +792,14 @@
 thread_join_m(int argc, VALUE *argv, VALUE self)
 {
     rb_thread_t *target_th;
+    rb_thread_t *cur_th = GET_THREAD();
     double delay = DELAY_INFTY;
     VALUE limit;
 
+    if (cur_th->in_trap) {
+	rb_raise(rb_eThreadError, "can't be called from trap context");
+    }
+
     GetThreadPtr(self, target_th);
 
     rb_scan_args(argc, argv, "01", &limit);
@@ -4773,6 +4780,8 @@
 	    th->async_errinfo_queue = rb_ary_tmp_new(0);
 	    th->async_errinfo_queue_checked = 0;
 	    th->async_errinfo_mask_stack = rb_ary_tmp_new(0);
+
+	    th->in_trap = 0;
 	}
     }
 
Index: test/ruby/test_thread.rb
===================================================================
--- test/ruby/test_thread.rb	(revision 37851)
+++ test/ruby/test_thread.rb	(revision 37852)
@@ -863,4 +863,19 @@
     end
     assert_in_delta(t1 - t0, 1, 1, bug5757)
   end
+
+  def test_thread_join_in_trap
+    assert_raise(ThreadError) {
+      t = Thread.new{ sleep 0.2; Process.kill(:INT, $$) }
+
+      Signal.trap :INT do
+        t.join
+      end
+
+      t.join
+    }
+  end
+
+
+
 end
Index: signal.c
===================================================================
--- signal.c	(revision 37851)
+++ signal.c	(revision 37852)
@@ -17,6 +17,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include "ruby_atomic.h"
+#include "eval_intern.h"
 
 #if defined(__native_client__) && defined(NACL_NEWLIB)
 # include "nacl/signal.h"
@@ -623,7 +624,22 @@
 signal_exec(VALUE cmd, int safe, int sig)
 {
     VALUE signum = INT2NUM(sig);
-    rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe);
+    rb_thread_t *cur_th = GET_THREAD();
+    int old_in_trap = cur_th->in_trap;
+    int state;
+
+    cur_th->in_trap = 1;
+    TH_PUSH_TAG(cur_th);
+    if ((state = EXEC_TAG()) == 0) {
+	rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe);
+    }
+    TH_POP_TAG();
+    cur_th->in_trap = old_in_trap;
+
+    if (state) {
+	/* XXX: should be replaced with rb_threadptr_async_errinfo_enque() */
+	JUMP_TAG(state);
+    }
 }
 
 void

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

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