diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-04-26 23:19:11 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-04-26 23:19:11 +0000 |
commit | c746b6fa42b1e68fb7284aa616d5ba7aef404dee (patch) | |
tree | 83221dc1a5e9ef7442bd0b5987c0e0f9deb5c476 /thread.c | |
parent | da12c793c4c7ae60b50b944791ad057de86cb527 (diff) | |
download | ruby-c746b6fa42b1e68fb7284aa616d5ba7aef404dee.tar.gz |
* thread.c (rb_threadptr_execute_interrupts_common):
handle timer_interrupt only on the first loop for the case to avoid
the infinite loop like following case:
* there is 2 Ruby threads (3 pthreads)
(1) main thread is waiting at gvl_yield:112 (native_cond_wait)
(2) sub thread works
(3) sub thread waits at gvl_yield:133 (native_mutex_unlock)
(4) main thread works
(5) main thread goes to gvl_acquire_common
(6) main thread call rb_wakeup_timer_thread
(7) timer thread set timer interrupt to the main thread
(8) main thread works
(9) main thread waits at gvl_acquire_common:64 (native_cond_wait)
(10) sub tread works
(11) set sub thread as the current thread
(12) run Ruby thread
(13) ...100ms
(14) sub thread goes to rb_threadptr_execute_interrupts_common
(15) sub thread call rb_thread_schedule_limits
(16) sub thread call gvl_release_common
(17) sub threads waits at gvl_yield:121 (native_cond_wait)
(18) main threads works
(19) main thread back to gvl_yield
(20) set main thread as the current thread
(21) main thread call gvl_yield
(22) main thread waits at gvl_yield:112 (native_cond_wait)
As described above, the main thread can't escape from
rb_threadptr_execute_interrupts_common.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35480 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread.c')
-rw-r--r-- | thread.c | 6 |
1 files changed, 6 insertions, 0 deletions
@@ -1273,6 +1273,7 @@ static void rb_threadptr_execute_interrupts_common(rb_thread_t *th) { rb_atomic_t interrupt; + int first_p = TRUE; if (th->raised_flag) return; @@ -1282,6 +1283,11 @@ rb_threadptr_execute_interrupts_common(rb_thread_t *th) int finalizer_interrupt = interrupt & 0x04; int sig; + if (first_p) + first_p = FALSE; + else if (interrupt == 0x01) + break; + th->status = THREAD_RUNNABLE; /* signal handling */ |