diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-08-22 16:19:18 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-08-22 16:19:18 +0000 |
commit | 832fd6825ce0878688cb60946fccd8a5289224b2 (patch) | |
tree | 25ec9e0d72189f7b6d62c4c4ba41f93b26d224b6 /thread.c | |
parent | 00b8444c930c3b9ce8c422c97496dd15bbf050e5 (diff) | |
download | ruby-832fd6825ce0878688cb60946fccd8a5289224b2.tar.gz |
* thread.c (rb_thread_schedule): don't recur infinitely.
(rb_threadptr_execute_interrupts): ditto.
[ruby-dev:38060]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24628 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread.c')
-rw-r--r-- | thread.c | 30 |
1 files changed, 23 insertions, 7 deletions
@@ -931,8 +931,10 @@ rb_thread_sleep(int sec) rb_thread_wait_for(rb_time_timeval(INT2FIX(sec))); } -void -rb_thread_schedule(void) +static void rb_threadptr_execute_interrupts_rec(rb_thread_t *, int); + +static void +rb_thread_schedule_rec(int sched_depth) { thread_debug("rb_thread_schedule\n"); if (!rb_thread_alone()) { @@ -950,10 +952,18 @@ rb_thread_schedule(void) rb_thread_set_current(th); thread_debug("rb_thread_schedule/switch done\n"); - RUBY_VM_CHECK_INTS(); + if (!sched_depth && UNLIKELY(GET_THREAD()->interrupt_flag)) { + rb_threadptr_execute_interrupts_rec(GET_THREAD(), sched_depth+1); + } } } +void +rb_thread_schedule(void) +{ + rb_thread_schedule_rec(0); +} + /* blocking region */ static inline void blocking_region_begin(rb_thread_t *th, struct rb_blocking_region_buffer *region, @@ -1183,8 +1193,8 @@ thread_s_pass(VALUE klass) * */ -void -rb_threadptr_execute_interrupts(rb_thread_t *th) +static void +rb_threadptr_execute_interrupts_rec(rb_thread_t *th, int sched_depth) { if (GET_VM()->main_thread == th) { while (rb_signal_buff_size() && !th->exec_signal) native_thread_yield(); @@ -1227,7 +1237,8 @@ rb_threadptr_execute_interrupts(rb_thread_t *th) rb_gc_finalize_deferred(); } - if (timer_interrupt) { + if (!sched_depth && timer_interrupt) { + sched_depth++; EXEC_EVENT_HOOK(th, RUBY_EVENT_SWITCH, th->cfp->self, 0, 0); if (th->slice > 0) { @@ -1235,7 +1246,7 @@ rb_threadptr_execute_interrupts(rb_thread_t *th) } else { reschedule: - rb_thread_schedule(); + rb_thread_schedule_rec(sched_depth+1); if (th->slice < 0) { th->slice++; goto reschedule; @@ -1248,6 +1259,11 @@ rb_threadptr_execute_interrupts(rb_thread_t *th) } } +void +rb_threadptr_execute_interrupts(rb_thread_t *th) +{ + rb_threadptr_execute_interrupts_rec(th, 0); +} void rb_gc_mark_threads(void) |