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