Skip to content

Instantly share code, notes, and snippets.

@kosaki
Created December 4, 2012 17:01
Show Gist options
  • Save kosaki/4206236 to your computer and use it in GitHub Desktop.
Save kosaki/4206236 to your computer and use it in GitHub Desktop.
diff --git a/thread_pthread.c b/thread_pthread.c
index d60cb41..4d055da 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -959,11 +959,13 @@ native_sleep(rb_thread_t *th, struct timeval *timeout_tv)
GVL_UNLOCK_BEGIN();
{
+ rb_thread_t *th = ruby_thread_from_native();
+
pthread_mutex_lock(lock);
th->unblock.func = ubf_pthread_cond_signal;
th->unblock.arg = th;
- if (RUBY_VM_INTERRUPTED(th)) {
+ if (RUBY_VM_INTERRUPTED(th) || th->status == THREAD_RUNNABLE) {
/* interrupted. return immediate */
thread_debug("native_sleep: interrupted before sleep\n");
}
@kosaki
Copy link
Author

kosaki commented Dec 4, 2012

  1. t1がスレッドt2, t3をつくる

  2. t1: t2にjoin。thread_join_m が join_listに自分をつなぐ

  3. t1: native_sleepの直前のCHECK_INTS_BLOCKINGで時間切れコンテキストスイッチ

  4. t2: 死ぬ。thread_func_2でt1のstatusをTHREAD_RUNNABLEにしてRUBY_VM_SET_INTERRUPT()する

  5. t3: 死ぬ

  6. t1: rb_execute_interrupt()でRUBY_VM_SET_INTERRUPTされているので、async errinfoキュー見るがなにも無いので抜ける

  7. t1 native_sleep。もうRUBY_VM_SET_INTERRUPTの痕跡は残っていないので、そのまま寝てしまう。もう起こしてくれる人はいないので刺さる

  8. で th->status が変わっているのでそれを見ればよい。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment