あけましておめでとうございます、なかむら(う)です。

In message "[ruby-cvs:28403] Ruby:r21185 (trunk): * thread.c (rb_thread_blocking_region): add a comment."
    on Dec.30,2008 16:57:54, <ko1 / ruby-lang.org> wrote:
| 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().

めでたくrb_thread_call_with_gvl()が入りましたが、rb_thread_t
に追加されたメンバblocking_region_bufferに値を設定していると
ころが存在しないような気がします。

あと、こっちはbugじゃなくてリクエストですが、C関数から自スレ
ッドがGVLを取得しているかどうかを判断するのが困難、というか、
rb_thread_call_with_gvl()内でやってるのと同じことをやる必要が
あって二度手間になるので、rb_thread_call_with_gvl()内でGVL取
得の有無を確認してよきに計らってくれた方がいいように思います。
# 以前ささださんにはIRCで「いらない」と言ってしまった気もしま
# すが、やっぱり必要でした。

いちおう、以上2点のパッチをつけておきます。

Index: thread.c =================================================================== --- thread.c (リビジョン 21276) +++ thread.c (作業コピー) @@ -954,6 +954,7 @@ { region->prev_status = th->status; set_unblock_function(th, func, arg, &region->oldubf); + th->blocking_region_buffer = region; th->status = THREAD_STOPPED; thread_debug("enter blocking region (%p)\n", (void *)th); rb_gc_save_machine_context(th); @@ -967,6 +968,7 @@ rb_thread_set_current(th); thread_debug("leave blocking region (%p)\n", (void *)th); remove_signal_thread_list(th); + th->blocking_region_buffer = NULL; reset_unblock_function(th, &region->oldubf); if (th->status == THREAD_STOPPED) { th->status = region->prev_status; @@ -1101,13 +1103,15 @@ } brb = (struct rb_blocking_region_buffer *)th->blocking_region_buffer; - prev_unblock = th->unblock; - - blocking_region_end(th, brb); + if (brb) { + 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); + /* leave from Ruby world: You can not access Ruby values, etc. */ + if (brb) + blocking_region_begin(th, brb, prev_unblock.func, prev_unblock.arg); return r; }
それでは。 -- U.Nakamura <usa / garbagecollect.jp>