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

ruby-changes:25873

From: kosaki <ko1@a...>
Date: Wed, 28 Nov 2012 17:31:04 +0900 (JST)
Subject: [ruby-changes:25873] kosaki:r37930 (trunk): * thread.c (struct rb_mutex_struct): add allow_trap field.

kosaki	2012-11-28 17:30:51 +0900 (Wed, 28 Nov 2012)

  New Revision: 37930

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

  Log:
    * thread.c (struct rb_mutex_struct): add allow_trap field.
    * internal.h (rb_mutex_allow_trap): added.
    * thread.c (rb_mutex_lock, rb_mutex_unlock): check mutex->allow_trap.
    * thread.c (mutex_sleep): remove trap check because it uses
      rb_mutex_lock and rb_mutex_unlock internally.
    * thread.c (rb_mutex_allow_trap): new helper function for the above.
    
    * io.c (io_binwrite): mark fptr->write_lock as writable in trap.
    
    * test/ruby/test_signal.rb (test_trap_puts): test for the above.

  Modified files:
    trunk/ChangeLog
    trunk/internal.h
    trunk/io.c
    trunk/test/ruby/test_signal.rb
    trunk/thread.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 37929)
+++ ChangeLog	(revision 37930)
@@ -1,3 +1,16 @@
+Wed Nov 28 16:21:46 2012  KOSAKI Motohiro  <kosaki.motohiro@g...>
+
+	* thread.c (struct rb_mutex_struct): add allow_trap field.
+	* internal.h (rb_mutex_allow_trap): added.
+	* thread.c (rb_mutex_lock, rb_mutex_unlock): check mutex->allow_trap.
+	* thread.c (mutex_sleep): remove trap check because it uses
+	  rb_mutex_lock and rb_mutex_unlock internally.
+	* thread.c (rb_mutex_allow_trap): new helper function for the above.
+
+	* io.c (io_binwrite): mark fptr->write_lock as writable in trap.
+
+	* test/ruby/test_signal.rb (test_trap_puts): test for the above.
+
 Wed Nov 28 16:59:12 2012  Koichi Sasada  <ko1@a...>
 
 	* proc.c: remove Proc#== and Proc#eql?.
Index: io.c
===================================================================
--- io.c	(revision 37929)
+++ io.c	(revision 37930)
@@ -1126,6 +1126,7 @@
         fptr->wbuf.capa = IO_WBUF_CAPA_MIN;
         fptr->wbuf.ptr = ALLOC_N(char, fptr->wbuf.capa);
 	fptr->write_lock = rb_mutex_new();
+	rb_mutex_allow_trap(fptr->write_lock, 1);
     }
     if ((!nosync && (fptr->mode & (FMODE_SYNC|FMODE_TTY))) ||
         (fptr->wbuf.ptr && fptr->wbuf.capa <= fptr->wbuf.len + len)) {
Index: thread.c
===================================================================
--- thread.c	(revision 37929)
+++ thread.c	(revision 37930)
@@ -342,6 +342,7 @@
     struct rb_thread_struct volatile *th;
     int cond_waiting;
     struct rb_mutex_struct *next_mutex;
+    int allow_trap;
 } rb_mutex_t;
 
 static void rb_mutex_abandon_all(rb_mutex_t *mutexes);
@@ -4140,16 +4141,15 @@
 rb_mutex_lock(VALUE self)
 {
     rb_thread_t *th = GET_THREAD();
+    rb_mutex_t *mutex;
+    GetMutexPtr(self, mutex);
 
     /* When running trap handler */
-    if (th->interrupt_mask & TRAP_INTERRUPT_MASK) {
+    if (!mutex->allow_trap && th->interrupt_mask & TRAP_INTERRUPT_MASK) {
 	rb_raise(rb_eThreadError, "can't be called from trap context");
     }
 
     if (rb_mutex_trylock(self) == Qfalse) {
-	rb_mutex_t *mutex;
-	GetMutexPtr(self, mutex);
-
 	if (mutex->th == GET_THREAD()) {
 	    rb_raise(rb_eThreadError, "deadlock; recursive locking");
 	}
@@ -4254,7 +4254,7 @@
     GetMutexPtr(self, mutex);
 
     /* When running trap handler */
-    if (GET_THREAD()->interrupt_mask & TRAP_INTERRUPT_MASK) {
+    if (!mutex->allow_trap && GET_THREAD()->interrupt_mask & TRAP_INTERRUPT_MASK) {
 	rb_raise(rb_eThreadError, "can't be called from trap context");
     }
 
@@ -4326,11 +4326,6 @@
 {
     VALUE timeout;
 
-    /* When running trap handler */
-    if (GET_THREAD()->interrupt_mask & TRAP_INTERRUPT_MASK) {
-	rb_raise(rb_eThreadError, "can't be called from trap context");
-    }
-
     rb_scan_args(argc, argv, "01", &timeout);
     return rb_mutex_sleep(self, timeout);
 }
@@ -4367,6 +4362,14 @@
     return rb_mutex_synchronize(self, rb_yield, Qnil);
 }
 
+void rb_mutex_allow_trap(VALUE self, int val)
+{
+    rb_mutex_t *m;
+    GetMutexPtr(self, m);
+
+    m->allow_trap = val;
+}
+
 /*
  * Document-class: ThreadShield
  */
Index: internal.h
===================================================================
--- internal.h	(revision 37929)
+++ internal.h	(revision 37930)
@@ -278,6 +278,7 @@
 VALUE rb_thread_shield_wait(VALUE self);
 VALUE rb_thread_shield_release(VALUE self);
 VALUE rb_thread_shield_destroy(VALUE self);
+void rb_mutex_allow_trap(VALUE self, int val);
 
 /* thread_pthread.c, thread_win32.c */
 void Init_native_thread(void);
Index: test/ruby/test_signal.rb
===================================================================
--- test/ruby/test_signal.rb	(revision 37929)
+++ test/ruby/test_signal.rb	(revision 37930)
@@ -260,4 +260,17 @@
       end
     end
   end
+
+  def test_trap_puts
+    assert_in_out_err([], <<-INPUT, ["a"*10000], [])
+      Signal.trap(:INT) {
+          # for enable internal io mutex
+          sync = false
+          # larger than internal io buffer
+          print "a"*10000
+      }
+      Process.kill :INT, $$
+      sleep 0.1
+    INPUT
+  end
 end

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

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