Commit 58d516f0 authored by Torge Matthies's avatar Torge Matthies Committed by Alexandre Julliard

msvcr100: Implement _StructuredTaskCollection canceling.

parent a3fc7a42
......@@ -1587,7 +1587,17 @@ static void test_StructuredTaskCollection(void)
ok(b, "SetEvent failed\n");
status = p__StructuredTaskCollection__RunAndWait(&task_coll, NULL);
todo_wine ok(status == 2, "_StructuredTaskCollection::_RunAndWait failed: %d\n", status);
ok(status == 2, "_StructuredTaskCollection::_RunAndWait failed: %d\n", status);
call_func1(p__StructuredTaskCollection_dtor, &task_coll);
/* cancel task collection without scheduled tasks */
call_func2(p__StructuredTaskCollection_ctor, &task_coll, NULL);
call_func1(p__StructuredTaskCollection__Cancel, &task_coll);
ok(task_coll.context == context, "Unexpected context: %p != %p\n", task_coll.context, context);
chore_ctor(&chore1);
status = p__StructuredTaskCollection__RunAndWait(&task_coll, NULL);
ok(status == 2, "_StructuredTaskCollection::_RunAndWait failed: %d\n", status);
ok(!chore1.executed, "Canceled collection executed chore\n");
call_func1(p__StructuredTaskCollection_dtor, &task_coll);
CloseHandle(chore_start_evt);
......
......@@ -1967,6 +1967,64 @@ struct execute_chore_data {
_StructuredTaskCollection *task_collection;
};
/* ?_Cancel@_StructuredTaskCollection@details@Concurrency@@QAAXXZ */
/* ?_Cancel@_StructuredTaskCollection@details@Concurrency@@QAEXXZ */
/* ?_Cancel@_StructuredTaskCollection@details@Concurrency@@QEAAXXZ */
DEFINE_THISCALL_WRAPPER(_StructuredTaskCollection__Cancel, 4)
void __thiscall _StructuredTaskCollection__Cancel(
_StructuredTaskCollection *this)
{
ThreadScheduler *scheduler;
void *prev_exception, *new_exception;
struct scheduled_chore *sc, *next;
LONG removed = 0;
LONG prev_finished, new_finished;
TRACE("(%p)\n", this);
if (!this->context)
this->context = get_current_context();
scheduler = get_thread_scheduler_from_context(this->context);
if (!scheduler)
return;
new_exception = this->exception;
do {
prev_exception = new_exception;
if ((ULONG_PTR)prev_exception & STRUCTURED_TASK_COLLECTION_CANCELLED)
return;
new_exception = (void*)((ULONG_PTR)prev_exception |
STRUCTURED_TASK_COLLECTION_CANCELLED);
} while ((new_exception = InterlockedCompareExchangePointer(
&this->exception, new_exception, prev_exception))
!= prev_exception);
EnterCriticalSection(&scheduler->cs);
LIST_FOR_EACH_ENTRY_SAFE(sc, next, &scheduler->scheduled_chores,
struct scheduled_chore, entry) {
if (sc->chore->task_collection != this)
continue;
sc->chore->task_collection = NULL;
list_remove(&sc->entry);
removed++;
operator_delete(sc);
}
LeaveCriticalSection(&scheduler->cs);
if (!removed)
return;
new_finished = this->finished;
do {
prev_finished = new_finished;
if (prev_finished == FINISHED_INITIAL)
new_finished = removed;
else
new_finished = prev_finished + removed;
} while ((new_finished = InterlockedCompareExchange(&this->finished,
new_finished, prev_finished)) != prev_finished);
RtlWakeAddressAll((LONG*)&this->finished);
}
static LONG CALLBACK execute_chore_except(EXCEPTION_POINTERS *pexc, void *_data)
{
struct execute_chore_data *data = _data;
......@@ -1976,6 +2034,8 @@ static LONG CALLBACK execute_chore_except(EXCEPTION_POINTERS *pexc, void *_data)
if (pexc->ExceptionRecord->ExceptionCode != CXX_EXCEPTION)
return EXCEPTION_CONTINUE_SEARCH;
_StructuredTaskCollection__Cancel(data->task_collection);
ptr = operator_new(sizeof(*ptr));
__ExceptionPtrCreate(ptr);
exception_ptr_from_record(ptr, pexc->ExceptionRecord);
......@@ -2216,19 +2276,11 @@ _TaskCollectionStatus __stdcall _StructuredTaskCollection__RunAndWait(
}
__FINALLY_CTX(exception_ptr_rethrow_finally, ep)
}
if (exception & STRUCTURED_TASK_COLLECTION_CANCELLED)
return TASK_COLLECTION_CANCELLED;
return TASK_COLLECTION_SUCCESS;
}
/* ?_Cancel@_StructuredTaskCollection@details@Concurrency@@QAAXXZ */
/* ?_Cancel@_StructuredTaskCollection@details@Concurrency@@QAEXXZ */
/* ?_Cancel@_StructuredTaskCollection@details@Concurrency@@QEAAXXZ */
DEFINE_THISCALL_WRAPPER(_StructuredTaskCollection__Cancel, 4)
void __thiscall _StructuredTaskCollection__Cancel(
_StructuredTaskCollection *this)
{
FIXME("(%p): stub!\n", this);
}
/* ?_IsCanceling@_StructuredTaskCollection@details@Concurrency@@QAA_NXZ */
/* ?_IsCanceling@_StructuredTaskCollection@details@Concurrency@@QAE_NXZ */
/* ?_IsCanceling@_StructuredTaskCollection@details@Concurrency@@QEAA_NXZ */
......
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