Yifu Wang : msvcr120: Fixed bugs in Concurrency::critical_section.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Feb 13 07:55:56 CST 2015


Module: wine
Branch: master
Commit: a11c8758b2e2c70d4a4cc5ad693b56ef7a5ad05d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=a11c8758b2e2c70d4a4cc5ad693b56ef7a5ad05d

Author: Yifu Wang <ywang at esri.com>
Date:   Tue Dec 30 15:03:36 2014 -0800

msvcr120: Fixed bugs in Concurrency::critical_section.

---

 dlls/msvcrt/lock.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/dlls/msvcrt/lock.c b/dlls/msvcrt/lock.c
index 328b5b5..6d903dc 100644
--- a/dlls/msvcrt/lock.c
+++ b/dlls/msvcrt/lock.c
@@ -384,10 +384,11 @@ void __thiscall critical_section_lock(critical_section *this)
         NtWaitForKeyedEvent(keyed_event, &q, 0, NULL);
     }
 
-    this->unk_active.next = NULL;
-    if(InterlockedCompareExchangePointer(&this->tail, &this->unk_active, &q) != &q)
-        spin_wait_for_next_cs(&q);
     cs_set_head(this, &q);
+    if(InterlockedCompareExchangePointer(&this->tail, &this->unk_active, &q) != &q) {
+        spin_wait_for_next_cs(&q);
+        this->unk_active.next = q.next;
+    }
 }
 
 /* ?try_lock at critical_section@Concurrency@@QAE_NXZ */
@@ -406,11 +407,11 @@ MSVCRT_bool __thiscall critical_section_try_lock(critical_section *this)
 
     memset(&q, 0, sizeof(q));
     if(!InterlockedCompareExchangePointer(&this->tail, &q, NULL)) {
-        this->unk_active.next = NULL;
-        if(InterlockedCompareExchangePointer(&this->tail, &this->unk_active, &q) != &q)
-            spin_wait_for_next_cs(&q);
-
         cs_set_head(this, &q);
+        if(InterlockedCompareExchangePointer(&this->tail, &this->unk_active, &q) != &q) {
+            spin_wait_for_next_cs(&q);
+            this->unk_active.next = q.next;
+        }
         return TRUE;
     }
     return FALSE;
@@ -437,8 +438,10 @@ void __thiscall critical_section_unlock(critical_section *this)
             break;
 
         next = this->unk_active.next;
-        if(InterlockedCompareExchangePointer(&this->tail, NULL, next) == next)
+        if(InterlockedCompareExchangePointer(&this->tail, NULL, next) == next) {
+            HeapFree(GetProcessHeap(), 0, next);
             return;
+        }
         spin_wait_for_next_cs(next);
 
         this->unk_active.next = next->next;
@@ -491,14 +494,18 @@ MSVCRT_bool __thiscall critical_section_try_lock_for(
         if(status == STATUS_TIMEOUT) {
             if(!InterlockedExchange(&q->free, TRUE))
                 return FALSE;
+            /* A thread has signaled the event and is block waiting. */
+            /* We need to catch the event to wake the thread.        */
+            NtWaitForKeyedEvent(keyed_event, q, 0, NULL);
         }
     }
 
-    this->unk_active.next = NULL;
-    if(InterlockedCompareExchangePointer(&this->tail, &this->unk_active, q) != q)
+    cs_set_head(this, q);
+    if(InterlockedCompareExchangePointer(&this->tail, &this->unk_active, q) != q) {
         spin_wait_for_next_cs(q);
+        this->unk_active.next = q->next;
+    }
 
-    cs_set_head(this, q);
     HeapFree(GetProcessHeap(), 0, q);
     return TRUE;
 }




More information about the wine-cvs mailing list