kernel32/tests: Fix race condition in the thread test.
This commit is contained in:
parent
43f2ec33bf
commit
ea39761d3a
|
@ -104,13 +104,15 @@ CreateThread
|
||||||
certain chunks of code at a time, and we know which one is executing
|
certain chunks of code at a time, and we know which one is executing
|
||||||
it. It basically makes multithreaded execution linear, which defeats
|
it. It basically makes multithreaded execution linear, which defeats
|
||||||
the purpose of multiple threads, but makes testing easy. */
|
the purpose of multiple threads, but makes testing easy. */
|
||||||
static HANDLE all_synced;
|
static HANDLE start_event, stop_event;
|
||||||
static LONG num_syncing_threads, num_synced;
|
static LONG num_syncing_threads, num_synced;
|
||||||
|
|
||||||
static void init_thread_sync_helpers(LONG num_threads)
|
static void init_thread_sync_helpers(LONG num_threads)
|
||||||
{
|
{
|
||||||
all_synced = CreateEvent(NULL, FALSE, FALSE, NULL);
|
start_event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
ok(all_synced != NULL, "CreateEvent failed\n");
|
ok(start_event != NULL, "CreateEvent failed\n");
|
||||||
|
stop_event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
ok(stop_event != NULL, "CreateEvent failed\n");
|
||||||
num_syncing_threads = num_threads;
|
num_syncing_threads = num_threads;
|
||||||
num_synced = 0;
|
num_synced = 0;
|
||||||
}
|
}
|
||||||
|
@ -120,13 +122,13 @@ static BOOL sync_threads_and_run_one(DWORD sync_id, DWORD my_id)
|
||||||
LONG num = InterlockedIncrement(&num_synced);
|
LONG num = InterlockedIncrement(&num_synced);
|
||||||
assert(0 < num && num <= num_syncing_threads);
|
assert(0 < num && num <= num_syncing_threads);
|
||||||
if (num == num_syncing_threads)
|
if (num == num_syncing_threads)
|
||||||
/* FIXME: MSDN claims PulseEvent is unreliable. For a test this isn't
|
{
|
||||||
so important, but we could use condition variables with more effort.
|
ResetEvent( stop_event );
|
||||||
The given approach is clearer, though. */
|
SetEvent( start_event );
|
||||||
PulseEvent(all_synced);
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DWORD ret = WaitForSingleObject(all_synced, 60000);
|
DWORD ret = WaitForSingleObject(start_event, 10000);
|
||||||
ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
|
ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
|
||||||
}
|
}
|
||||||
return sync_id == my_id;
|
return sync_id == my_id;
|
||||||
|
@ -137,18 +139,21 @@ static void resync_after_run(void)
|
||||||
LONG num = InterlockedDecrement(&num_synced);
|
LONG num = InterlockedDecrement(&num_synced);
|
||||||
assert(0 <= num && num < num_syncing_threads);
|
assert(0 <= num && num < num_syncing_threads);
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
PulseEvent(all_synced);
|
{
|
||||||
|
ResetEvent( start_event );
|
||||||
|
SetEvent( stop_event );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DWORD ret = WaitForSingleObject(all_synced, 60000);
|
DWORD ret = WaitForSingleObject(stop_event, 10000);
|
||||||
ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
|
ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cleanup_thread_sync_helpers(void)
|
static void cleanup_thread_sync_helpers(void)
|
||||||
{
|
{
|
||||||
CloseHandle(all_synced);
|
CloseHandle(start_event);
|
||||||
all_synced = NULL;
|
CloseHandle(stop_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD tlsIndex;
|
DWORD tlsIndex;
|
||||||
|
|
Loading…
Reference in New Issue