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

ruby-changes:26168

From: kosaki <ko1@a...>
Date: Thu, 6 Dec 2012 04:37:58 +0900 (JST)
Subject: [ruby-changes:26168] kosaki:r38225 (trunk): * thread.c (rb_uninterruptible): helper function for providing

kosaki	2012-12-06 04:37:49 +0900 (Thu, 06 Dec 2012)

  New Revision: 38225

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

  Log:
    * thread.c (rb_uninterruptible): helper function for providing
      temporary async_interrupt_timing(Object => :defer)
    
    * io.c (rb_f_p): use rb_uninterruptible.
    * io.c (rb_f_p_internal): helper function for rb_f_p().
    * io.c (struct rb_f_p_arg): new struct for rb_f_p_internal.
    
    * test/ruby/test_thread.rb (test_async_interrupt_and_p): test for
      the above.

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

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 38224)
+++ ChangeLog	(revision 38225)
@@ -1,3 +1,15 @@
+Thu Dec  6 04:34:19 2012  KOSAKI Motohiro  <kosaki.motohiro@g...>
+
+	* thread.c (rb_uninterruptible): helper function for providing
+	  temporary async_interrupt_timing(Object => :defer)
+
+	* io.c (rb_f_p): use rb_uninterruptible.
+	* io.c (rb_f_p_internal): helper function for rb_f_p().
+	* io.c (struct rb_f_p_arg): new struct for rb_f_p_internal.
+
+	* test/ruby/test_thread.rb (test_async_interrupt_and_p): test for
+	  the above.
+
 Thu Dec  6 04:27:10 2012  KOSAKI Motohiro  <kosaki.motohiro@g...>
 
 	* io.c (io_binwrite): check interrupt before io issue.
Index: io.c
===================================================================
--- io.c	(revision 38224)
+++ io.c	(revision 38225)
@@ -6759,6 +6759,35 @@
     }
 }
 
+struct rb_f_p_arg {
+    int argc;
+    VALUE *argv;
+};
+
+static VALUE
+rb_f_p_internal(VALUE arg)
+{
+    struct rb_f_p_arg *arg1 = (struct rb_f_p_arg*)arg;
+    int argc = arg1->argc;
+    VALUE *argv = arg1->argv;
+    int i;
+    VALUE ret = Qnil;
+
+    for (i=0; i<argc; i++) {
+	rb_p(argv[i]);
+    }
+    if (argc == 1) {
+	ret = argv[0];
+    }
+    else if (argc > 1) {
+	ret = rb_ary_new4(argc, argv);
+    }
+    if (RB_TYPE_P(rb_stdout, T_FILE)) {
+	rb_io_flush(rb_stdout);
+    }
+    return ret;
+}
+
 /*
  *  call-seq:
  *     p(obj)              -> obj
@@ -6780,22 +6809,11 @@
 static VALUE
 rb_f_p(int argc, VALUE *argv, VALUE self)
 {
-    int i;
-    VALUE ret = Qnil;
+    struct rb_f_p_arg arg;
+    arg.argc = argc;
+    arg.argv = argv;
 
-    for (i=0; i<argc; i++) {
-	rb_p(argv[i]);
-    }
-    if (argc == 1) {
-	ret = argv[0];
-    }
-    else if (argc > 1) {
-	ret = rb_ary_new4(argc, argv);
-    }
-    if (RB_TYPE_P(rb_stdout, T_FILE)) {
-	rb_io_flush(rb_stdout);
-    }
-    return ret;
+    return rb_uninterruptible(rb_f_p_internal, (VALUE)&arg);
 }
 
 /*
Index: thread.c
===================================================================
--- thread.c	(revision 38224)
+++ thread.c	(revision 38225)
@@ -5048,3 +5048,15 @@
     GET_VM()->coverages = Qfalse;
     rb_remove_event_hook(update_coverage);
 }
+
+VALUE
+rb_uninterruptible(VALUE (*b_proc)(ANYARGS), VALUE data)
+{
+    VALUE interrupt_mask = rb_hash_new();
+    rb_thread_t *cur_th = GET_THREAD();
+
+    rb_hash_aset(interrupt_mask, rb_cObject, ID2SYM(rb_intern("defer")));
+    rb_ary_push(cur_th->async_errinfo_mask_stack, interrupt_mask);
+
+    return rb_ensure(b_proc, data, rb_ary_pop, cur_th->async_errinfo_mask_stack);
+}
Index: internal.h
===================================================================
--- internal.h	(revision 38224)
+++ internal.h	(revision 38225)
@@ -279,6 +279,7 @@
 VALUE rb_thread_shield_release(VALUE self);
 VALUE rb_thread_shield_destroy(VALUE self);
 void rb_mutex_allow_trap(VALUE self, int val);
+VALUE rb_uninterruptible(VALUE (*b_proc)(ANYARGS), VALUE data);
 
 /* thread_pthread.c, thread_win32.c */
 void Init_native_thread(void);
Index: test/ruby/test_thread.rb
===================================================================
--- test/ruby/test_thread.rb	(revision 38224)
+++ test/ruby/test_thread.rb	(revision 38225)
@@ -637,6 +637,26 @@
     INPUT
   end
 
+  def test_async_interrupt_and_p
+    assert_in_out_err([], <<-INPUT, %w(:ok :ok), [])
+      th_waiting = true
+
+      t = Thread.new {
+        Thread.async_interrupt_timing(RuntimeError => :on_blocking) {
+          nil while th_waiting
+          # p shouldn't provide interruptible point
+          p :ok
+          p :ok
+        }
+      }
+
+      sleep 0.1
+      t.raise RuntimeError
+      th_waiting = false
+      t.join rescue nil
+    INPUT
+  end
+
   def test_async_interrupted?
     q = Queue.new
     Thread.async_interrupt_timing(RuntimeError => :defer){

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

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