зеркало из https://github.com/github/ruby.git
* 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
This commit is contained in:
Родитель
da12c793c4
Коммит
c746b6fa42
31
ChangeLog
31
ChangeLog
|
@ -1,3 +1,34 @@
|
|||
Fri Apr 27 01:45:05 2012 NARUSE, Yui <naruse@ruby-lang.org>
|
||||
|
||||
* 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.
|
||||
|
||||
Fri Apr 27 07:15:07 2012 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* ext/socket/socket.c (sock_s_pack_sockaddr_un): support the longest
|
||||
|
|
6
thread.c
6
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 */
|
||||
|
|
Загрузка…
Ссылка в новой задаче