Module: wine Branch: master Commit: bcda5979bec20702d9773d8e38737bf51da25d80 URL: https://gitlab.winehq.org/wine/wine/-/commit/bcda5979bec20702d9773d8e38737bf...
Author: Piotr Caban piotr@codeweavers.com Date: Thu Jan 18 19:56:25 2024 +0100
concrt140: Add _Cancellation_beacon::_Confirm_cancel() implementation.
---
dlls/msvcr120/tests/msvcr120.c | 30 ++++++++++++++++++++++++------ dlls/msvcrt/concurrency.c | 14 ++++++++++---- 2 files changed, 34 insertions(+), 10 deletions(-)
diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c index 672be695c3d..c76db6582cf 100644 --- a/dlls/msvcr120/tests/msvcr120.c +++ b/dlls/msvcr120/tests/msvcr120.c @@ -184,7 +184,7 @@ typedef struct _UnrealizedChore } _UnrealizedChore;
typedef struct { - MSVCRT_bool *cancelling; + long *cancelling; } _Cancellation_beacon;
static char* (CDECL *p_setlocale)(int category, const char* locale); @@ -262,6 +262,7 @@ static MSVCRT_bool (__thiscall *p__StructuredTaskCollection__IsCanceling)(_Struc
static _Cancellation_beacon* (__thiscall *p__Cancellation_beacon_ctor)(_Cancellation_beacon*); static void (__thiscall *p__Cancellation_beacon_dtor)(_Cancellation_beacon*); +static MSVCRT_bool (__thiscall *p__Cancellation_beacon__Confirm_cancel)(_Cancellation_beacon*);
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(module,y) #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0) @@ -368,6 +369,8 @@ static BOOL init(void) "??0_Cancellation_beacon@details@Concurrency@@QEAA@XZ"); SET(p__Cancellation_beacon_dtor, "??1_Cancellation_beacon@details@Concurrency@@QEAA@XZ"); + SET(p__Cancellation_beacon__Confirm_cancel, + "?_Confirm_cancel@_Cancellation_beacon@details@Concurrency@@QEAA_NXZ"); } else { #ifdef __arm__ SET(p__StructuredTaskCollection_ctor, @@ -416,6 +419,8 @@ static BOOL init(void) "??0_Cancellation_beacon@details@Concurrency@@QAA@XZ"); SET(p__Cancellation_beacon_dtor, "??1_Cancellation_beacon@details@Concurrency@@QAA@XZ"); + SET(p__Cancellation_beacon__Confirm_cancel, + "?_Confirm_cancel@_Cancellation_beacon@details@Concurrency@@QAA_NXZ"); #else SET(p__StructuredTaskCollection_ctor, "??0_StructuredTaskCollection@details@Concurrency@@QAE@PAV_CancellationTokenState@12@@Z"); @@ -463,6 +468,8 @@ static BOOL init(void) "??0_Cancellation_beacon@details@Concurrency@@QAE@XZ"); SET(p__Cancellation_beacon_dtor, "??1_Cancellation_beacon@details@Concurrency@@QAE@XZ"); + SET(p__Cancellation_beacon__Confirm_cancel, + "?_Confirm_cancel@_Cancellation_beacon@details@Concurrency@@QAE_NXZ"); #endif SET(p_Context_CurrentContext, "?CurrentContext@Context@Concurrency@@SAPAV12@XZ"); @@ -1415,11 +1422,16 @@ static void __cdecl chore_proc(_UnrealizedChore *_this) "IsCurrentTaskCollectionCanceling returned TRUE\n");
call_func1(p__Cancellation_beacon_ctor, &beacon); - ok(!*beacon.cancelling, "beacon signalled %x\n", *beacon.cancelling); + ok(!*beacon.cancelling, "beacon signalled %lx\n", *beacon.cancelling);
call_func1(p__Cancellation_beacon_ctor, &beacon2); ok(beacon.cancelling != beacon2.cancelling, "beacons point to the same data\n"); - ok(!*beacon.cancelling, "beacon signalled %x\n", *beacon.cancelling); + ok(!*beacon.cancelling, "beacon signalled %lx\n", *beacon.cancelling); + + canceling = call_func1(p__Cancellation_beacon__Confirm_cancel, &beacon); + ok(!canceling, "_Confirm_cancel returned TRUE\n"); + ok(*beacon.cancelling == -1, "beacon signalled %lx\n", *beacon.cancelling); + *beacon.cancelling = 0; }
if (!chore->wait_event) @@ -1448,13 +1460,19 @@ static void __cdecl chore_proc(_UnrealizedChore *_this) ok(p_Context_IsCurrentTaskCollectionCanceling(), "IsCurrentTaskCollectionCanceling returned FALSE\n");
- ok(*beacon.cancelling == 1, "beacon not signalled (%x)\n", *beacon.cancelling); + ok(*beacon.cancelling == 1, "beacon not signalled (%lx)\n", *beacon.cancelling); + canceling = call_func1(p__Cancellation_beacon__Confirm_cancel, &beacon); + ok(canceling, "_Confirm_cancel returned FALSE\n"); + ok(*beacon.cancelling == 1, "beacon not signalled (%lx)\n", *beacon.cancelling); call_func1(p__Cancellation_beacon_dtor, &beacon); - ok(*beacon2.cancelling == 1, "beacon not signalled (%x)\n", *beacon2.cancelling); + ok(*beacon2.cancelling == 1, "beacon not signalled (%lx)\n", *beacon2.cancelling); call_func1(p__Cancellation_beacon_dtor, &beacon2);
call_func1(p__Cancellation_beacon_ctor, &beacon); - ok(*beacon.cancelling == 1, "beacon not signalled (%x)\n", *beacon.cancelling); + ok(*beacon.cancelling == 1, "beacon not signalled (%lx)\n", *beacon.cancelling); + canceling = call_func1(p__Cancellation_beacon__Confirm_cancel, &beacon); + ok(canceling, "_Confirm_cancel returned FALSE\n"); + ok(*beacon.cancelling == 1, "beacon not signalled (%lx)\n", *beacon.cancelling); call_func1(p__Cancellation_beacon_dtor, &beacon); } } diff --git a/dlls/msvcrt/concurrency.c b/dlls/msvcrt/concurrency.c index 74bd8193476..68091c21e60 100644 --- a/dlls/msvcrt/concurrency.c +++ b/dlls/msvcrt/concurrency.c @@ -98,7 +98,7 @@ struct scheduler_list { };
struct beacon { - bool cancelling; + LONG cancelling; struct list entry; struct _StructuredTaskCollection *task_collection; }; @@ -2143,7 +2143,7 @@ void __thiscall _StructuredTaskCollection__Cancel( EnterCriticalSection(&((ExternalContextBase*)this->context)->beacons_cs); LIST_FOR_EACH_ENTRY(beacon, &((ExternalContextBase*)this->context)->beacons, struct beacon, entry) { if (beacon->task_collection == this) - beacon->cancelling = TRUE; + InterlockedIncrement(&beacon->cancelling); } LeaveCriticalSection(&((ExternalContextBase*)this->context)->beacons_cs);
@@ -3112,8 +3112,14 @@ void __thiscall _Cancellation_beacon_dtor(_Cancellation_beacon *this) DEFINE_THISCALL_WRAPPER(_Cancellation_beacon__Confirm_cancel, 4) bool __thiscall _Cancellation_beacon__Confirm_cancel(_Cancellation_beacon *this) { - FIXME("(%p)\n", this); - return TRUE; + bool ret; + + TRACE("(%p)\n", this); + + ret = Context_IsCurrentTaskCollectionCanceling(); + if (!ret) + InterlockedDecrement(&this->beacon->cancelling); + return ret; }
/* ??0_Condition_variable@details@Concurrency@@QAE@XZ */