Commit a240d380 authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

msvcr110: Use Context blocking functions in _StructuredTaskCollection class.

parent a035c639
...@@ -193,7 +193,7 @@ typedef struct _StructuredTaskCollection ...@@ -193,7 +193,7 @@ typedef struct _StructuredTaskCollection
volatile LONG count; volatile LONG count;
volatile LONG finished; volatile LONG finished;
void *exception; void *exception;
void *event; Context *event;
} _StructuredTaskCollection; } _StructuredTaskCollection;
bool __thiscall _StructuredTaskCollection__IsCanceling(_StructuredTaskCollection*); bool __thiscall _StructuredTaskCollection__IsCanceling(_StructuredTaskCollection*);
...@@ -2118,8 +2118,8 @@ void __thiscall _StructuredTaskCollection__Cancel( ...@@ -2118,8 +2118,8 @@ void __thiscall _StructuredTaskCollection__Cancel(
ThreadScheduler *scheduler; ThreadScheduler *scheduler;
void *prev_exception, *new_exception; void *prev_exception, *new_exception;
struct scheduled_chore *sc, *next; struct scheduled_chore *sc, *next;
LONG removed = 0, finished = 1;
struct beacon *beacon; struct beacon *beacon;
LONG removed = 0;
TRACE("(%p)\n", this); TRACE("(%p)\n", this);
...@@ -2162,8 +2162,9 @@ void __thiscall _StructuredTaskCollection__Cancel( ...@@ -2162,8 +2162,9 @@ void __thiscall _StructuredTaskCollection__Cancel(
return; return;
if (InterlockedCompareExchange(&this->finished, removed, FINISHED_INITIAL) != FINISHED_INITIAL) if (InterlockedCompareExchange(&this->finished, removed, FINISHED_INITIAL) != FINISHED_INITIAL)
InterlockedAdd(&this->finished, removed); finished = InterlockedAdd(&this->finished, removed);
RtlWakeAddressAll((LONG*)&this->finished); if (!finished)
call_Context_Unblock(this->event);
} }
static LONG CALLBACK execute_chore_except(EXCEPTION_POINTERS *pexc, void *_data) static LONG CALLBACK execute_chore_except(EXCEPTION_POINTERS *pexc, void *_data)
...@@ -2240,21 +2241,20 @@ static void execute_chore(_UnrealizedChore *chore, ...@@ -2240,21 +2241,20 @@ static void execute_chore(_UnrealizedChore *chore,
static void CALLBACK chore_wrapper_finally(BOOL normal, void *data) static void CALLBACK chore_wrapper_finally(BOOL normal, void *data)
{ {
_UnrealizedChore *chore = data; _UnrealizedChore *chore = data;
LONG count;
volatile LONG *ptr; volatile LONG *ptr;
LONG finished = 1;
TRACE("(%u %p)\n", normal, data); TRACE("(%u %p)\n", normal, data);
if (!chore->task_collection) if (!chore->task_collection)
return; return;
ptr = &chore->task_collection->finished; ptr = &chore->task_collection->finished;
count = chore->task_collection->count;
chore->task_collection = NULL;
if (InterlockedCompareExchange(ptr, 1, FINISHED_INITIAL) != FINISHED_INITIAL) if (InterlockedCompareExchange(ptr, 1, FINISHED_INITIAL) != FINISHED_INITIAL)
InterlockedIncrement(ptr); finished = InterlockedIncrement(ptr);
if (*ptr >= count) if (!finished)
RtlWakeAddressSingle((LONG*)ptr); call_Context_Unblock(chore->task_collection->event);
chore->task_collection = NULL;
} }
static void __cdecl chore_wrapper(_UnrealizedChore *chore) static void __cdecl chore_wrapper(_UnrealizedChore *chore)
...@@ -2393,9 +2393,9 @@ static void CALLBACK exception_ptr_rethrow_finally(BOOL normal, void *data) ...@@ -2393,9 +2393,9 @@ static void CALLBACK exception_ptr_rethrow_finally(BOOL normal, void *data)
_TaskCollectionStatus __stdcall _StructuredTaskCollection__RunAndWait( _TaskCollectionStatus __stdcall _StructuredTaskCollection__RunAndWait(
_StructuredTaskCollection *this, _UnrealizedChore *chore) _StructuredTaskCollection *this, _UnrealizedChore *chore)
{ {
LONG expected, val;
ULONG_PTR exception; ULONG_PTR exception;
exception_ptr *ep; exception_ptr *ep;
LONG count;
TRACE("(%p %p)\n", this, chore); TRACE("(%p %p)\n", this, chore);
...@@ -2415,12 +2415,17 @@ _TaskCollectionStatus __stdcall _StructuredTaskCollection__RunAndWait( ...@@ -2415,12 +2415,17 @@ _TaskCollectionStatus __stdcall _StructuredTaskCollection__RunAndWait(
} }
} }
expected = this->count ? this->count : FINISHED_INITIAL; this->event = get_current_context();
while ((val = this->finished) != expected) InterlockedCompareExchange(&this->finished, 0, FINISHED_INITIAL);
RtlWaitOnAddress((LONG*)&this->finished, &val, sizeof(val), NULL);
this->finished = 0; while (this->count != 0) {
this->count = 0; count = this->count;
InterlockedAdd(&this->count, -count);
count = InterlockedAdd(&this->finished, -count);
if (count < 0)
call_Context_Block(this->event);
}
exception = (ULONG_PTR)this->exception; exception = (ULONG_PTR)this->exception;
ep = (exception_ptr*)(exception & ~STRUCTURED_TASK_COLLECTION_STATUS_MASK); ep = (exception_ptr*)(exception & ~STRUCTURED_TASK_COLLECTION_STATUS_MASK);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment