Added by metanest (Makoto Kishimoto) over 14 years ago. Updated over 13 years ago.
Description
=begin [ruby-dev:41434] =end
Files
=begin 直接的な原因はGVLのデッドロックなんだけど
static int garbage_collect_with_gvl(rb_objspace_t *objspace) { if (dont_gc) return TRUE; if (ruby_thread_has_gvl_p()) { return garbage_collect(objspace); } else { if (ruby_native_thread_p()) { return (int)(VALUE)rb_thread_call_with_gvl(gc_with_gvl, (void )objspace); } else { / no ruby thread */ fprintf(stderr, "[FATAL] failed to allocate memory\n"); exit(EXIT_FAILURE); } } }
のようにGVLをもってないことを確認してから、GVLを取りに行っているのに pthread_mutex_lock が EDEADLK を返したので大混乱。と。 そういうバグなわけだな(たぶん)
=end
=begin ここかな?
#define blocking_region_begin(th, region, func, arg) do { (region)->prev_status = (th)->status; (th)->blocking_region_buffer = (region); \ ☆ ここでruby_thread_has_gvl_p()が偽を返すようになる set_unblock_function((th), (func), (arg), &(region)->oldubf); \ ★ ここでシグナルをチェックしてしまうのでSIGINTが見つかると rb_interrupt() が呼ばれてしまう (th)->status = THREAD_STOPPED; thread_debug("enter blocking region (%p)\n", (void *)(th)); RB_GC_SAVE_MACHINE_CONTEXT(th); native_mutex_unlock(&(th)->vm->global_vm_lock); \ ☆ ここで実際のGVLのアンロック } while (0)
=begin 親切な人がレビューしてくれないかなー(チラッチラッ と修正パッチ(案)を添付します =end
=begin This issue was solved with changeset r28055. Makoto, thank you for reporting this issue. Your contribution to Ruby is greatly appreciated. May Ruby be with you.
Also available in: Atom PDF