[2/3] user32: Add some tests for EndDialog called from other thread.
Dmitry Timoshkov
dmitry at baikal.ru
Thu Apr 30 05:04:05 CDT 2015
These tests pass under Wine.
Testbot failures are not related to this patch.
---
dlls/user32/tests/msg.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 113 insertions(+)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index f2ba805..2b054ab 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -14869,6 +14869,117 @@ todo_wine
flush_sequence();
}
+static const struct message end_dialog_1[] = {
+ { WM_USER, sent|wparam|lparam, 0, 0 },
+ { 0 }
+};
+static const struct message end_dialog_2[] = {
+ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE },
+ { WM_USER, sent|wparam|lparam, 0, 0 },
+ { 0 }
+};
+static const struct message destroy_window[] = {
+ { HCBT_DESTROYWND, hook },
+ { 0x0090, sent|optional },
+ { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_DESTROY, sent },
+ { WM_NCDESTROY, sent },
+ { 0 }
+};
+
+static LONG EndDialog_ret;
+
+static DWORD WINAPI EndDialog_thread(void *param)
+{
+ struct wnd_event *wnd_event = param;
+
+ trace("thread: starting\n");
+ WaitForSingleObject(wnd_event->start_event, INFINITE);
+
+ /* make sure that GetMessage is called by main thread */
+ Sleep(100);
+
+ PostMessageA(wnd_event->hwnd, WM_USER, 0, 0);
+
+ trace("thread: call EndDialog\n");
+ EndDialog(wnd_event->hwnd, 0);
+ trace("thread: ret EndDialog\n");
+
+ InterlockedIncrement(&EndDialog_ret);
+
+ return 0;
+}
+
+static void test_EndDialog_other_thread(BOOL wait_send_message)
+{
+ DWORD qs_all_input = QS_ALLINPUT & ~QS_RAWINPUT;
+ HANDLE hthread;
+ struct wnd_event wnd_event;
+ DWORD tid, ret;
+ MSG msg;
+
+ EndDialog_ret = 0;
+
+ wnd_event.start_event = CreateEventA(NULL, 0, 0, NULL);
+
+ wnd_event.hwnd = CreateDialogParamA(GetModuleHandleA(NULL), "TEST_EMPTY_DIALOG", 0, test_dlg_proc, 0);
+ ok(wnd_event.hwnd != 0, "CreateWindowEx failed\n");
+
+ hthread = CreateThread(NULL, 0, EndDialog_thread, &wnd_event, 0, &tid);
+ ok(hthread != NULL, "CreateThread failed, error %d\n", GetLastError());
+
+ flush_events();
+ flush_sequence();
+
+ ret = GetQueueStatus(QS_SENDMESSAGE);
+ ok(ret == 0, "wrong status %08x\n", ret);
+
+ SetEvent(wnd_event.start_event);
+
+ /* wait for other thread's SendMessage */
+ if (wait_send_message)
+ {
+ for (;;)
+ {
+ ret = GetQueueStatus(QS_SENDMESSAGE);
+ if (ret == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE)) break;
+ Sleep(50);
+ }
+ }
+ trace("main: call GetMessage\n");
+ GetMessageA(&msg, 0, 0, 0);
+ ok(msg.message == WM_USER, "expected WM_USER, got %04x\n", msg.message);
+ DispatchMessageA(&msg);
+ if (!wait_send_message)
+ ok_sequence(end_dialog_1, "EndDialog from other thread", FALSE);
+ else
+ ok_sequence(end_dialog_2, "EndDialog from other thread", FALSE);
+
+ /* intentionally yield */
+ MsgWaitForMultipleObjects(0, NULL, FALSE, 100, qs_all_input);
+
+ trace("main: call DestroyWindow\n");
+ DestroyWindow(wnd_event.hwnd);
+ trace("main: ret DestroyWindow\n");
+ ok_sequence(destroy_window, "DestroyWindow", FALSE);
+
+ ret = InterlockedIncrement(&EndDialog_ret);
+ if (!wait_send_message)
+ ok(EndDialog_ret == 1, "expected 1, got %u\n", ret);
+ else
+ ok(EndDialog_ret == 2, "expected 2, got %u\n", ret);
+
+ trace("waiting for thread exit\n");
+ WaitForSingleObject(hthread, INFINITE);
+ CloseHandle(hthread);
+
+ ret = InterlockedIncrement(&EndDialog_ret);
+ ok(EndDialog_ret == 3, "expected 3, got %u\n", ret);
+
+ flush_events();
+ flush_sequence();
+}
+
static void init_funcs(void)
{
HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
@@ -14947,6 +15058,8 @@ START_TEST(msg)
}
hEvent_hook = 0;
+ test_EndDialog_other_thread(FALSE);
+ test_EndDialog_other_thread(TRUE);
test_SendMessage_other_thread(1);
test_SendMessage_other_thread(2);
test_SetFocus();
--
2.3.7
More information about the wine-patches
mailing list