ruby-changes:54225
From: normal <ko1@a...>
Date: Wed, 19 Dec 2018 03:26:00 +0900 (JST)
Subject: [ruby-changes:54225] normal:r66446 (trunk): thread_pthread.c (ubf_timer_destroy): more careful state transition
normal 2018-12-19 03:25:54 +0900 (Wed, 19 Dec 2018) New Revision: 66446 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=66446 Log: thread_pthread.c (ubf_timer_destroy): more careful state transition We must not call timer_destroy while another thread is calling timer_settime to arm the timer. cf. http://ci.rvm.jp/results/trunk-iseq_binary@silicon-docker/1541578 Modified files: trunk/thread_pthread.c Index: thread_pthread.c =================================================================== --- thread_pthread.c (revision 66445) +++ thread_pthread.c (revision 66446) @@ -1787,11 +1787,34 @@ ubf_timer_destroy(void) https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L1787 { #if UBF_TIMER == UBF_TIMER_POSIX if (timer_posix.owner == getpid()) { - /* prevent signal handler from arming: */ - ATOMIC_SET(timer_posix.state, RTIMER_DEAD); + rb_atomic_t expect = RTIMER_DISARM; + size_t i, max = 10000000; - if (timer_settime(timer_posix.timerid, 0, &zero, 0)) - rb_bug_errno("timer_settime (destroy)", errno); + /* prevent signal handler from arming: */ + for (i = 0; i < max; i++) { + switch (ATOMIC_CAS(timer_posix.state, expect, RTIMER_DEAD)) { + case RTIMER_DISARM: + if (expect == RTIMER_DISARM) goto done; + expect = RTIMER_DISARM; + break; + case RTIMER_ARMING: + native_thread_yield(); /* let another thread finish arming */ + expect = RTIMER_ARMED; + break; + case RTIMER_ARMED: + if (expect == RTIMER_ARMED) { + if (timer_settime(timer_posix.timerid, 0, &zero, 0)) + rb_bug_errno("timer_settime (destroy)", errno); + goto done; + } + expect = RTIMER_ARMED; + break; + case RTIMER_DEAD: + rb_bug("RTIMER_DEAD unexpected"); + } + } + rb_bug("timed out waiting for timer to arm"); +done: if (timer_delete(timer_posix.timerid) < 0) rb_sys_fail("timer_delete"); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/