Module: wine Branch: master Commit: 5c574f68b8164653cc8cf05719f153320d64cc6c URL: https://gitlab.winehq.org/wine/wine/-/commit/5c574f68b8164653cc8cf05719f1533...
Author: Piotr Caban piotr@codeweavers.com Date: Fri Aug 25 15:46:06 2023 +0200
msvcr120/tests: Add _Cancellation_beacon tests.
---
dlls/msvcr120/tests/msvcr120.c | 44 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+)
diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c index 11a8594e749..d21e73244c2 100644 --- a/dlls/msvcr120/tests/msvcr120.c +++ b/dlls/msvcr120/tests/msvcr120.c @@ -183,6 +183,10 @@ typedef struct _UnrealizedChore void *unk[6]; } _UnrealizedChore;
+typedef struct { + MSVCRT_bool *cancelling; +} _Cancellation_beacon; + static char* (CDECL *p_setlocale)(int category, const char* locale); static struct MSVCRT_lconv* (CDECL *p_localeconv)(void); static size_t (CDECL *p_wcstombs_s)(size_t *ret, char* dest, size_t sz, const wchar_t* src, size_t max); @@ -255,6 +259,9 @@ static int (__stdcall *p__StructuredTaskCollection__RunAndWait)(_StructuredTaskC static void (__thiscall *p__StructuredTaskCollection__Cancel)(_StructuredTaskCollection*); static MSVCRT_bool (__thiscall *p__StructuredTaskCollection__IsCanceling)(_StructuredTaskCollection*);
+static _Cancellation_beacon* (__thiscall *p__Cancellation_beacon_ctor)(_Cancellation_beacon*); +static void (__thiscall *p__Cancellation_beacon_dtor)(_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)
@@ -355,6 +362,10 @@ static BOOL init(void) "?notify_all@_Condition_variable@details@Concurrency@@QEAAXXZ"); SET(p_Context_CurrentContext, "?CurrentContext@Context@Concurrency@@SAPEAV12@XZ"); + SET(p__Cancellation_beacon_ctor, + "??0_Cancellation_beacon@details@Concurrency@@QEAA@XZ"); + SET(p__Cancellation_beacon_dtor, + "??1_Cancellation_beacon@details@Concurrency@@QEAA@XZ"); } else { #ifdef __arm__ SET(p__StructuredTaskCollection_ctor, @@ -399,6 +410,10 @@ static BOOL init(void) "?notify_one@_Condition_variable@details@Concurrency@@QAAXXZ"); SET(p__Condition_variable_notify_all, "?notify_all@_Condition_variable@details@Concurrency@@QAAXXZ"); + SET(p__Cancellation_beacon_ctor, + "??0_Cancellation_beacon@details@Concurrency@@QAA@XZ"); + SET(p__Cancellation_beacon_dtor, + "??1_Cancellation_beacon@details@Concurrency@@QAA@XZ"); #else SET(p__StructuredTaskCollection_ctor, "??0_StructuredTaskCollection@details@Concurrency@@QAE@PAV_CancellationTokenState@12@@Z"); @@ -442,6 +457,10 @@ static BOOL init(void) "?notify_one@_Condition_variable@details@Concurrency@@QAEXXZ"); SET(p__Condition_variable_notify_all, "?notify_all@_Condition_variable@details@Concurrency@@QAEXXZ"); + SET(p__Cancellation_beacon_ctor, + "??0_Cancellation_beacon@details@Concurrency@@QAE@XZ"); + SET(p__Cancellation_beacon_dtor, + "??1_Cancellation_beacon@details@Concurrency@@QAE@XZ"); #endif SET(p_Context_CurrentContext, "?CurrentContext@Context@Concurrency@@SAPAV12@XZ"); @@ -1366,6 +1385,7 @@ struct chore static void __cdecl chore_proc(_UnrealizedChore *_this) { struct chore *chore = CONTAINING_RECORD(_this, struct chore, chore); + _Cancellation_beacon beacon, beacon2;
if (chore->start_event) { @@ -1388,6 +1408,13 @@ static void __cdecl chore_proc(_UnrealizedChore *_this) p__StructuredTaskCollection__IsCanceling, chore->chore.task_collection); ok(!canceling, "Task is already canceling\n"); + + call_func1(p__Cancellation_beacon_ctor, &beacon); + ok(!*beacon.cancelling, "beacon signalled %x\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); }
if (!chore->wait_event) @@ -1412,6 +1439,15 @@ static void __cdecl chore_proc(_UnrealizedChore *_this) p__StructuredTaskCollection__IsCanceling, chore->chore.task_collection); ok(canceling, "Task is not canceling\n"); + + ok(*beacon.cancelling == 1, "beacon not signalled (%x)\n", *beacon.cancelling); + call_func1(p__Cancellation_beacon_dtor, &beacon); + ok(*beacon2.cancelling == 1, "beacon not signalled (%x)\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); + call_func1(p__Cancellation_beacon_dtor, &beacon); } }
@@ -1426,6 +1462,7 @@ static void test_StructuredTaskCollection(void) HANDLE chore_start_evt, chore_evt1, chore_evt2; _StructuredTaskCollection task_coll; struct chore chore1, chore2; + _Cancellation_beacon beacon; DWORD main_thread_id; Context *context; int status; @@ -1585,13 +1622,20 @@ static void test_StructuredTaskCollection(void) ret = WaitForSingleObject(chore_evt1, 5000); ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %ld\n", ret);
+ call_func1(p__Cancellation_beacon_ctor, &beacon); + ok(!*beacon.cancelling, "beacon signalled\n"); + call_func1(p__StructuredTaskCollection__Cancel, &task_coll); + ok(!*beacon.cancelling, "beacon signalled\n");
b = SetEvent(chore_evt2); ok(b, "SetEvent failed\n"); + ok(!*beacon.cancelling, "beacon signalled\n");
status = p__StructuredTaskCollection__RunAndWait(&task_coll, NULL); ok(status == 2, "_StructuredTaskCollection::_RunAndWait failed: %d\n", status); + ok(!*beacon.cancelling, "beacon signalled\n"); + call_func1(p__Cancellation_beacon_dtor, &beacon); call_func1(p__StructuredTaskCollection_dtor, &task_coll);
/* cancel task collection without scheduled tasks */