kernel32/tests: Fix race condition in the thread test.

This commit is contained in:
Alexandre Julliard 2008-09-19 12:21:45 +02:00
parent 43f2ec33bf
commit ea39761d3a
1 changed files with 17 additions and 12 deletions

View File

@ -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;