On 6/25/2019 3:43 AM, Corinna Vinschen wrote: > Hi Ken, > > On Jun 24 20:19, Ken Brown wrote: >> If a timer expires while the timerfd thread is in its inner loop, >> check for the thread cancellation event before trying to enter >> a_critical_section. It's possible that timerfd_tracker::dtor has >> entered its critical section and is trying to cancel the thread. See >> http://www.cygwin.org/ml/cygwin/2019-06/msg00096.html. >> --- >> winsup/cygwin/timerfd.cc | 5 +++++ >> 1 file changed, 5 insertions(+) >> >> diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc >> index 8e4c94e66..e8261ef2e 100644 >> --- a/winsup/cygwin/timerfd.cc >> +++ b/winsup/cygwin/timerfd.cc >> @@ -137,6 +137,11 @@ timerfd_tracker::thread_func () >> continue; >> } >> >> + /* Avoid a deadlock if dtor has just entered its critical >> + section and is trying to cancel the thread. */ >> + if (IsEventSignalled (cancel_evt)) >> + goto canceled; > > This looks still racy, what if cancel_evt is set just between the > IsEventSignalled() and enter_critical_section() calls? > > Hmm. > > What if we redefine enter_critical_section() to return three > states. It calls WFMO on cancel_evt and _access_mtx, in this order, > so that a cancel event is honored. Or maybe introduce another > function like enter_critical_section_cancelable() which is only > called in this single instance in timerfd_tracker::thread_func?
Yes, that's much better. I'll send v2 shortly, after some testing. Ken