From: Nobuyoshi Nakada Date: 2007-07-23T17:15:25+09:00 Subject: [ruby-dev:31280] Re: is_ruby_native_thread() なかだです。 At Mon, 23 Jul 2007 12:54:43 +0900, Hidetoshi NAGAI wrote in [ruby-dev:31276]: > 一つは,外部ライブラリがその内部ルーチンで native thread を > 生成する可能性があるケースです. > ruby への call が一切無いことが保証されるならいいのですが, > そうでない場合には毎回のチェックを必要とする可能性があります. native threadからruby threadに結びつける方法があったほうがいい ですか? > >  あと、is_* という名前はあれなので、出来れば rb_ がついたナイ > > スな名前になるといいなぁ、とは思います。互換性の点から難しいかな。 > > これは変更しちゃってもいいと思います. > is_ruby_native_thread() でのチェックを必要とするようなライブラリは, > 1.9 対応のためには,多分,それなりの量の書き直しを必要とするでしょうから. なにがいいですかねぇ。 Index: thread.c =================================================================== --- thread.c (revision 12839) +++ thread.c (working copy) @@ -2966,4 +2966,4 @@ int is_ruby_native_thread(void) { - return Qtrue; + return ruby_thread_from_native() ? Qtrue : Qfalse; } Index: thread_pthread.ci =================================================================== --- thread_pthread.ci (revision 12839) +++ thread_pthread.ci (working copy) @@ -73,4 +73,6 @@ static void remove_signal_thread_list(rb static rb_thread_lock_t signal_thread_list_lock; +static pthread_key_t ruby_native_thread_key; + static void null_func() @@ -80,11 +82,28 @@ null_func() static void -Init_native_thread() +init_ruby_nathive_thread_key(void) +{ + pthread_key_create(&ruby_native_thread_key, NULL); +} + +static void +Init_native_thread(void) { - GET_THREAD()->thread_id = pthread_self(); + pthread_once_t key_once = PTHREAD_ONCE_INIT; + rb_thread_t *th = GET_THREAD(); + + pthread_once(&key_once, init_ruby_nathive_thread_key); + th->thread_id = pthread_self(); + pthread_setspecific(ruby_native_thread_key, th); native_mutex_initialize(&signal_thread_list_lock); posix_signal(SIGVTALRM, null_func); } +static rb_thread_t * +ruby_thread_from_native(void) +{ + return pthread_getspecific(ruby_native_thread_key); +} + static void native_thread_destroy(rb_thread_t *th) Index: thread_win32.ci =================================================================== --- thread_win32.ci (revision 12839) +++ thread_win32.ci (working copy) @@ -21,8 +21,24 @@ #define remove_signal_thread_list(th) +static volatile DWORD ruby_native_thread_key = TLS_OUT_OF_INDEXES; + static void Init_native_thread() { + static LONG wait_flag = -1; rb_thread_t *th = GET_THREAD(); + + while (ruby_native_thread_key == TLS_OUT_OF_INDEXES) { + if (InterlockedIncrement(&wait_flag) > 0) { + InterlockedDecrement(&wait_flag); + Sleep(1); + } + else { + ruby_native_thread_key = TlsAlloc(); + InterlockedDecrement(&wait_flag); + break; + } + } + TlsSetValue(ruby_native_thread_key, th); DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), @@ -37,4 +53,10 @@ Init_native_thread() } +static rb_thread_t * +ruby_thread_from_native(void) +{ + return TlsGetValue(ruby_native_thread_key); +} + static void w32_error(void) -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦