Skip to content

Commit

Permalink
msvcr120/tests: Add _Cancellation_beacon tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
PiotrCW authored and julliard committed Aug 28, 2023
1 parent 5672c08 commit 5c574f6
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions dlls/msvcr120/tests/msvcr120.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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)
{
Expand All @@ -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)
Expand All @@ -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);
}
}

Expand All @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit 5c574f6

Please sign in to comment.