在 2019/4/12 22:45, JonY via Mingw-w64-public 写道: > On 4/12/19 1:49 AM, Andrew Ng wrote: >> I have attached a minimal patch that fixes the deadlock issue. >> >> The principle change to avoid deadlock, is to not wait whilst holding the >> "waiters count lock". Because of this change to the locking, there is an >> additional case required in the "signal" and "broadcast" functions which >> handles when the "waiters count" goes to zero. >> >> I'm away on holiday (vacation), so will probably not have time to sort out >> the other changes that were included in my original patch which are >> probably still worth while, particularly the removal of the locking from >> the "sema" functions. > > Can you resend with a .txt file extension? The patch did not make it to > the mailing list. >
I got it because I was on the To: list. Now here it is. -- Best regards, LH_Mouse
diff --git a/mingw-w64-libraries/winpthreads/src/cond.c
b/mingw-w64-libraries/winpthreads/src/cond.c
index 368ee8a7..a2db042c 100644
--- a/mingw-w64-libraries/winpthreads/src/cond.c
+++ b/mingw-w64-libraries/winpthreads/src/cond.c
@@ -324,17 +324,26 @@ pthread_cond_signal (pthread_cond_t *c)
}
else if (_c->waiters_count_ > _c->waiters_count_gone_)
{
+ LeaveCriticalSection (&_c->waiters_count_lock_);
r = do_sema_b_wait (_c->sema_b, 1,
INFINITE,&_c->waiters_b_lock_,&_c->value_b);
if (r != 0)
{
- LeaveCriticalSection (&_c->waiters_count_lock_);
/* pthread_testcancel(); */
return r;
}
+ EnterCriticalSection (&_c->waiters_count_lock_);
if (_c->waiters_count_gone_ != 0)
{
_c->waiters_count_ -= _c->waiters_count_gone_;
_c->waiters_count_gone_ = 0;
+ if (_c->waiters_count_ == 0)
+ {
+ _c->waiters_count_unblock_ = 0;
+ LeaveCriticalSection (&_c->waiters_count_lock_);
+ r = do_sema_b_release (_c->sema_b, 1, &_c->waiters_b_lock_,
&_c->value_b);
+ /* pthread_testcancel(); */
+ return r;
+ }
}
_c->waiters_count_ -= 1;
_c->waiters_count_unblock_ = 1;
@@ -382,17 +391,26 @@ pthread_cond_broadcast (pthread_cond_t *c)
}
else if (_c->waiters_count_ > _c->waiters_count_gone_)
{
+ LeaveCriticalSection (&_c->waiters_count_lock_);
r = do_sema_b_wait (_c->sema_b, 1,
INFINITE,&_c->waiters_b_lock_,&_c->value_b);
if (r != 0)
{
- LeaveCriticalSection (&_c->waiters_count_lock_);
/* pthread_testcancel(); */
return r;
}
+ EnterCriticalSection (&_c->waiters_count_lock_);
if (_c->waiters_count_gone_ != 0)
{
_c->waiters_count_ -= _c->waiters_count_gone_;
_c->waiters_count_gone_ = 0;
+ if (_c->waiters_count_ == 0)
+ {
+ _c->waiters_count_unblock_ = 0;
+ LeaveCriticalSection (&_c->waiters_count_lock_);
+ r = do_sema_b_release (_c->sema_b, 1, &_c->waiters_b_lock_,
&_c->value_b);
+ /* pthread_testcancel(); */
+ return r;
+ }
}
relCnt = _c->waiters_count_;
_c->waiters_count_ = 0;
@@ -488,7 +506,9 @@ pthread_cond_timedwait_impl (pthread_cond_t *c,
pthread_mutex_t *external_mutex,
r = do_sema_b_wait (_c->sema_b, 0,
INFINITE,&_c->waiters_b_lock_,&_c->value_b);
if (r != 0)
return r;
+ EnterCriticalSection (&_c->waiters_count_lock_);
_c->waiters_count_++;
+ LeaveCriticalSection (&_c->waiters_count_lock_);
r = do_sema_b_release (_c->sema_b, 1,&_c->waiters_b_lock_,&_c->value_b);
if (r != 0)
return r;
@@ -535,13 +555,14 @@ cleanup_wait (void *arg)
else if ((INT_MAX/2) - 1 == _c->waiters_count_gone_)
{
_c->waiters_count_gone_ += 1;
+ LeaveCriticalSection (&_c->waiters_count_lock_);
r = do_sema_b_wait (_c->sema_b, 1,
INFINITE,&_c->waiters_b_lock_,&_c->value_b);
if (r != 0)
{
- LeaveCriticalSection(&_c->waiters_count_lock_);
ch->r[0] = r;
return;
}
+ EnterCriticalSection (&_c->waiters_count_lock_);
_c->waiters_count_ -= _c->waiters_count_gone_;
r = do_sema_b_release (_c->sema_b, 1,&_c->waiters_b_lock_,&_c->value_b);
if (r != 0)
signature.asc
Description: PGP signature
_______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
