在 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)

Attachment: signature.asc
Description: PGP signature

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to