summaryrefslogtreecommitdiff
path: root/thread.c
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-26 23:19:11 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-26 23:19:11 +0000
commitc746b6fa42b1e68fb7284aa616d5ba7aef404dee (patch)
tree83221dc1a5e9ef7442bd0b5987c0e0f9deb5c476 /thread.c
parentda12c793c4c7ae60b50b944791ad057de86cb527 (diff)
* 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.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/thread.c b/thread.c
index 7383a886f6..a63c9528de 100644
--- a/thread.c
+++ b/thread.c
@@ -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 */