user32/tests: Add more synchronization in the exit thread test to avoid races.
This commit is contained in:
parent
39398aedc7
commit
52ad8123f9
|
@ -6315,7 +6315,9 @@ static void test_paint_messages(void)
|
||||||
struct wnd_event
|
struct wnd_event
|
||||||
{
|
{
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
HANDLE event;
|
HANDLE grand_child;
|
||||||
|
HANDLE start_event;
|
||||||
|
HANDLE stop_event;
|
||||||
};
|
};
|
||||||
|
|
||||||
static DWORD WINAPI thread_proc(void *param)
|
static DWORD WINAPI thread_proc(void *param)
|
||||||
|
@ -6327,7 +6329,7 @@ static DWORD WINAPI thread_proc(void *param)
|
||||||
100, 100, 200, 200, 0, 0, 0, NULL);
|
100, 100, 200, 200, 0, 0, 0, NULL);
|
||||||
ok(wnd_event->hwnd != 0, "Failed to create overlapped window\n");
|
ok(wnd_event->hwnd != 0, "Failed to create overlapped window\n");
|
||||||
|
|
||||||
SetEvent(wnd_event->event);
|
SetEvent(wnd_event->start_event);
|
||||||
|
|
||||||
while (GetMessage(&msg, 0, 0, 0))
|
while (GetMessage(&msg, 0, 0, 0))
|
||||||
{
|
{
|
||||||
|
@ -6351,13 +6353,13 @@ static DWORD CALLBACK create_grand_child_thread( void *param )
|
||||||
ok (hchild != 0, "Failed to create child window\n");
|
ok (hchild != 0, "Failed to create child window\n");
|
||||||
flush_events();
|
flush_events();
|
||||||
flush_sequence();
|
flush_sequence();
|
||||||
SetEvent( wnd_event->event );
|
SetEvent( wnd_event->start_event );
|
||||||
|
|
||||||
while (GetMessage(&msg, 0, 0, 0))
|
for (;;)
|
||||||
{
|
{
|
||||||
TranslateMessage(&msg);
|
MsgWaitForMultipleObjects(0, NULL, FALSE, 1000, QS_ALLINPUT);
|
||||||
DispatchMessage(&msg);
|
|
||||||
if (!IsWindow( hchild )) break; /* will be destroyed when parent thread exits */
|
if (!IsWindow( hchild )) break; /* will be destroyed when parent thread exits */
|
||||||
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -6366,7 +6368,7 @@ static DWORD CALLBACK create_child_thread( void *param )
|
||||||
{
|
{
|
||||||
struct wnd_event *wnd_event = param;
|
struct wnd_event *wnd_event = param;
|
||||||
struct wnd_event child_event;
|
struct wnd_event child_event;
|
||||||
DWORD tid;
|
DWORD ret, tid;
|
||||||
MSG msg;
|
MSG msg;
|
||||||
|
|
||||||
child_event.hwnd = CreateWindowExA(0, "TestWindowClass", "Test child",
|
child_event.hwnd = CreateWindowExA(0, "TestWindowClass", "Test child",
|
||||||
|
@ -6375,15 +6377,16 @@ static DWORD CALLBACK create_child_thread( void *param )
|
||||||
SetFocus( child_event.hwnd );
|
SetFocus( child_event.hwnd );
|
||||||
flush_events();
|
flush_events();
|
||||||
flush_sequence();
|
flush_sequence();
|
||||||
child_event.event = wnd_event->event;
|
child_event.start_event = wnd_event->start_event;
|
||||||
CloseHandle( CreateThread(NULL, 0, create_grand_child_thread, &child_event, 0, &tid) );
|
wnd_event->grand_child = CreateThread(NULL, 0, create_grand_child_thread, &child_event, 0, &tid);
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
DWORD ret = MsgWaitForMultipleObjects(1, &child_event.event, FALSE, 1000, QS_SENDMESSAGE);
|
DWORD ret = MsgWaitForMultipleObjects(1, &child_event.start_event, FALSE, 1000, QS_SENDMESSAGE);
|
||||||
if (ret != 1) break;
|
if (ret != 1) break;
|
||||||
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
Sleep( 200 ); /* leave parent the time to finish processing messages */
|
ret = WaitForSingleObject( wnd_event->stop_event, 5000 );
|
||||||
|
ok( !ret, "WaitForSingleObject failed %x\n", ret );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6398,8 +6401,8 @@ static void test_interthread_messages(void)
|
||||||
struct wnd_event wnd_event;
|
struct wnd_event wnd_event;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
wnd_event.event = CreateEventW(NULL, 0, 0, NULL);
|
wnd_event.start_event = CreateEventW(NULL, 0, 0, NULL);
|
||||||
if (!wnd_event.event)
|
if (!wnd_event.start_event)
|
||||||
{
|
{
|
||||||
win_skip("skipping interthread message test under win9x\n");
|
win_skip("skipping interthread message test under win9x\n");
|
||||||
return;
|
return;
|
||||||
|
@ -6408,9 +6411,9 @@ static void test_interthread_messages(void)
|
||||||
hThread = CreateThread(NULL, 0, thread_proc, &wnd_event, 0, &tid);
|
hThread = CreateThread(NULL, 0, thread_proc, &wnd_event, 0, &tid);
|
||||||
ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
|
ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
|
||||||
|
|
||||||
ok(WaitForSingleObject(wnd_event.event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
|
ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
|
||||||
|
|
||||||
CloseHandle(wnd_event.event);
|
CloseHandle(wnd_event.start_event);
|
||||||
|
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ok(!DestroyWindow(wnd_event.hwnd), "DestroyWindow succeded\n");
|
ok(!DestroyWindow(wnd_event.hwnd), "DestroyWindow succeded\n");
|
||||||
|
@ -6460,20 +6463,28 @@ static void test_interthread_messages(void)
|
||||||
ok (wnd_event.hwnd != 0, "Failed to create parent window\n");
|
ok (wnd_event.hwnd != 0, "Failed to create parent window\n");
|
||||||
flush_sequence();
|
flush_sequence();
|
||||||
log_all_parent_messages++;
|
log_all_parent_messages++;
|
||||||
wnd_event.event = CreateEventA( NULL, TRUE, FALSE, NULL );
|
wnd_event.start_event = CreateEventA( NULL, TRUE, FALSE, NULL );
|
||||||
|
wnd_event.stop_event = CreateEventA( NULL, TRUE, FALSE, NULL );
|
||||||
hThread = CreateThread( NULL, 0, create_child_thread, &wnd_event, 0, &tid );
|
hThread = CreateThread( NULL, 0, create_child_thread, &wnd_event, 0, &tid );
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
ret = MsgWaitForMultipleObjects(1, &wnd_event.event, FALSE, 1000, QS_SENDMESSAGE);
|
ret = MsgWaitForMultipleObjects(1, &wnd_event.start_event, FALSE, 1000, QS_SENDMESSAGE);
|
||||||
if (ret != 1) break;
|
if (ret != 1) break;
|
||||||
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
ok( !ret, "MsgWaitForMultipleObjects failed %x\n", ret );
|
ok( !ret, "MsgWaitForMultipleObjects failed %x\n", ret );
|
||||||
/* now wait for the thread without processing messages; this shouldn't deadlock */
|
/* now wait for the thread without processing messages; this shouldn't deadlock */
|
||||||
|
SetEvent( wnd_event.stop_event );
|
||||||
ret = WaitForSingleObject( hThread, 5000 );
|
ret = WaitForSingleObject( hThread, 5000 );
|
||||||
ok( !ret, "WaitForSingleObject failed %x\n", ret );
|
ok( !ret, "WaitForSingleObject failed %x\n", ret );
|
||||||
CloseHandle( hThread );
|
CloseHandle( hThread );
|
||||||
CloseHandle( wnd_event.event );
|
|
||||||
|
ret = WaitForSingleObject( wnd_event.grand_child, 5000 );
|
||||||
|
ok( !ret, "WaitForSingleObject failed %x\n", ret );
|
||||||
|
CloseHandle( wnd_event.grand_child );
|
||||||
|
|
||||||
|
CloseHandle( wnd_event.start_event );
|
||||||
|
CloseHandle( wnd_event.stop_event );
|
||||||
flush_events();
|
flush_events();
|
||||||
ok_sequence(WmExitThreadSeq, "destroy child on thread exit", FALSE);
|
ok_sequence(WmExitThreadSeq, "destroy child on thread exit", FALSE);
|
||||||
log_all_parent_messages--;
|
log_all_parent_messages--;
|
||||||
|
@ -10210,7 +10221,7 @@ static const struct message WmShowMaximized_2[] = {
|
||||||
};
|
};
|
||||||
static const struct message WmShowMaximized_3[] = {
|
static const struct message WmShowMaximized_3[] = {
|
||||||
{ HCBT_MINMAX, hook|lparam, 0, SW_SHOWMAXIMIZED },
|
{ HCBT_MINMAX, hook|lparam, 0, SW_SHOWMAXIMIZED },
|
||||||
{ WM_GETMINMAXINFO, sent },
|
{ WM_GETMINMAXINFO, sent|optional },
|
||||||
{ WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_STATECHANGED, 0, SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOSIZE|SWP_NOMOVE },
|
{ WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_STATECHANGED, 0, SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOSIZE|SWP_NOMOVE },
|
||||||
{ HCBT_ACTIVATE, hook|optional }, /* win2000 doesn't send it */
|
{ HCBT_ACTIVATE, hook|optional }, /* win2000 doesn't send it */
|
||||||
{ WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2000 doesn't send it */
|
{ WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2000 doesn't send it */
|
||||||
|
|
Loading…
Reference in New Issue