[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