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

ruby-changes:9645

From: ko1 <ko1@a...>
Date: Tue, 30 Dec 2008 16:58:13 +0900 (JST)
Subject: [ruby-changes:9645] Ruby:r21185 (trunk): * thread.c (rb_thread_blocking_region): add a comment.

ko1	2008-12-30 16:57:53 +0900 (Tue, 30 Dec 2008)

  New Revision: 21185

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

  Log:
    * thread.c (rb_thread_blocking_region): add a comment.
    * thread.c (rb_thread_call_without_gvl): added as a alias of
      rb_thread_blocking_region().
    * thread.c (rb_thread_call_with_gvl): added.
    * vm_core.h (rb_thread_t#blocking_region_buffer): added for
      rb_thread_call_with_gvl().

  Modified files:
    trunk/ChangeLog
    trunk/thread.c
    trunk/vm_core.h

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 21184)
+++ ChangeLog	(revision 21185)
@@ -1,3 +1,15 @@
+Tue Dec 30 16:56:09 2008  Koichi Sasada  <ko1@a...>
+
+	* thread.c (rb_thread_blocking_region): add a comment.
+
+	* thread.c (rb_thread_call_without_gvl): added as a alias of
+	  rb_thread_blocking_region().
+
+	* thread.c (rb_thread_call_with_gvl): added.
+
+	* vm_core.h (rb_thread_t#blocking_region_buffer): added for
+	  rb_thread_call_with_gvl().
+
 Mon Dec 29 23:41:42 2008  Koichi Sasada  <ko1@a...>
 
 	* ext/dl/test/test_base.rb: add libc search logic.
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 21184)
+++ vm_core.h	(revision 21185)
@@ -363,6 +363,7 @@
     int slice;
 
     native_thread_data_t native_thread_data;
+    void *blocking_region_buffer;
 
     VALUE thgroup;
     VALUE value;
Index: thread.c
===================================================================
--- thread.c	(revision 21184)
+++ thread.c	(revision 21185)
@@ -1014,9 +1014,14 @@
  *
  *   NOTE: You can not execute most of Ruby C API and touch Ruby objects
  *         in `func()' and `ubf()' because current thread doesn't acquire
- *         GVL (cause synchronization problem).  If you need to do it,
+ *         GVL (cause synchronization problem).  Especially, ALLOC*() are
+ *         forbidden because they are related to GC.  If you need to do it,
  *         read source code of C APIs and confirm by yourself.
  *
+ *   NOTE: In short, this API is difficult to use safely.  I recommend you
+ *         use other ways if you have.  We lack experiences to use this API.
+ *         Please report your problem related on it.
+ *
  *   Safe C API:
  *     * rb_thread_interrupted() - check interrupt flag
  */
@@ -1040,7 +1045,73 @@
     return val;
 }
 
+/* alias of rb_thread_blocking_region() */
+
+VALUE
+rb_thread_call_without_gvl(
+    rb_blocking_function_t *func, void *data1,
+    rb_unblock_function_t *ubf, void *data2)
+{
+    return rb_thread_blocking_region(func, data1, ubf, data2);
+}
+
 /*
+ * rb_thread_call_with_gvl - re-enter into Ruby world while releasing GVL.
+ *
+ * While releasing GVL using rb_thread_blocking_region() or
+ * rb_thread_call_without_gvl(), you can not access Ruby values or invoke methods.
+ * If you need to access it, you must use this function rb_thread_call_with_gvl().
+ *
+ * This function rb_thread_call_with_gvl() does:
+ * (1) acquire GVL.
+ * (2) call passed function `func'.
+ * (3) release GVL.
+ * (4) return a value which is returned at (2).
+ *
+ * NOTE: You should not return Ruby object at (2) because such Object
+ *       will not marked.
+ *
+ * NOTE: If an exception is raised in `func', this function "DOES NOT"
+ *       protect (catch) the exception.  If you have any resources
+ *       which should free before throwing exception, you need use
+ *       rb_protect() in `func' and return a value which represents
+ *       exception is raised.
+ *
+ * NOTE: This functions should not be called by a thread which
+ *       is not created as Ruby thread (created by Thread.new or so).
+ *       In other words, this function *DOES NOT* associate
+ *       NON-Ruby thread to Ruby thread.
+ */
+void *
+rb_thread_call_with_gvl(void *(*func)(void *), void *data1)
+{
+    rb_thread_t *th = ruby_thread_from_native();
+    struct rb_blocking_region_buffer *brb;
+    struct rb_unblock_callback prev_unblock;
+    void *r;
+
+    if (th == 0) {
+	/* Error is occurred, but we can't use rb_bug()
+	 * because this thread is not Ruby's thread.
+         * What should we do?
+	 */
+
+	fprintf(stderr, "[BUG] rb_thread_call_with_gvl() is called by non-ruby thread\n");
+	exit(1);
+    }
+
+    brb = (struct rb_blocking_region_buffer *)th->blocking_region_buffer;
+    prev_unblock = th->unblock;
+
+    blocking_region_end(th, brb);
+    /* enter to Ruby world: You can access Ruby values, methods and so on. */
+    r = (*func)(data1);
+    /* levae from Ruby world: You can not access Ruby values, etc. */
+    blocking_region_begin(th, brb, prev_unblock.func, prev_unblock.arg);
+    return r;
+}
+
+/*
  *  call-seq:
  *     Thread.pass   => nil
  *

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

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