Dmitry Timoshkov : user32/tests: Add a test for sending inter-thread messages.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Apr 20 08:24:42 CDT 2015
Module: wine
Branch: master
Commit: 4ae80d15d957d627529a912e9cd9b7dd1ea1daea
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4ae80d15d957d627529a912e9cd9b7dd1ea1daea
Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date: Mon Apr 20 18:54:06 2015 +0800
user32/tests: Add a test for sending inter-thread messages.
---
dlls/user32/tests/msg.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 150 insertions(+)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 5f10a89..b014dd9 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -14598,6 +14598,153 @@ static void test_TrackPopupMenuEmpty(void)
DestroyWindow(hwnd);
}
+static const struct message send_message_1[] = {
+ { WM_USER+2, sent|wparam|lparam, 0, 0 },
+ { WM_USER, sent|wparam|lparam, 0, 0 },
+ { 0 }
+};
+static const struct message send_message_2[] = {
+ { WM_USER+4, sent|wparam|lparam, 0, 0 },
+ { 0 }
+};
+static const struct message send_message_3[] = {
+ { WM_USER+3, sent|wparam|lparam, 0, 0 },
+ { WM_USER+1, sent|wparam|lparam, 0, 0 },
+ { 0 }
+};
+
+static DWORD WINAPI SendMessage_thread_1(void *param)
+{
+ struct wnd_event *wnd_event = param;
+
+ trace("thread: starting\n");
+ WaitForSingleObject(wnd_event->start_event, INFINITE);
+
+ trace("thread: call PostMessage\n");
+ PostMessageA(wnd_event->hwnd, WM_USER, 0, 0);
+
+ trace("thread: call PostMessage\n");
+ PostMessageA(wnd_event->hwnd, WM_USER+1, 0, 0);
+
+ trace("thread: call SendMessage\n");
+ SendMessageA(wnd_event->hwnd, WM_USER+2, 0, 0);
+
+ trace("thread: call SendMessage\n");
+ SendMessageA(wnd_event->hwnd, WM_USER+3, 0, 0);
+
+ return 0;
+}
+
+static DWORD WINAPI SendMessage_thread_2(void *param)
+{
+ struct wnd_event *wnd_event = param;
+
+ trace("thread: starting\n");
+ WaitForSingleObject(wnd_event->start_event, INFINITE);
+
+ trace("thread: call PostMessage\n");
+ PostMessageA(wnd_event->hwnd, WM_USER, 0, 0);
+
+ trace("thread: call PostMessage\n");
+ PostMessageA(wnd_event->hwnd, WM_USER+1, 0, 0);
+
+ /* this leads to sending an internal message under Wine */
+ trace("thread: call EnableWindow\n");
+ EnableWindow(wnd_event->hwnd, TRUE);
+
+ trace("thread: call SendMessage\n");
+ SendMessageA(wnd_event->hwnd, WM_USER+2, 0, 0);
+
+ trace("thread: call SendMessage\n");
+ SendMessageA(wnd_event->hwnd, WM_USER+3, 0, 0);
+
+ return 0;
+}
+
+static void test_SendMessage_other_thread(int thread_n)
+{
+ DWORD qs_all_input = QS_ALLINPUT & ~QS_RAWINPUT;
+ HANDLE hthread;
+ struct wnd_event wnd_event;
+ DWORD tid, ret;
+ MSG msg;
+
+ wnd_event.start_event = CreateEventA(NULL, 0, 0, NULL);
+
+ wnd_event.hwnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
+ 100, 100, 200, 200, 0, 0, 0, NULL);
+ ok(wnd_event.hwnd != 0, "CreateWindowEx failed\n");
+
+ hthread = CreateThread(NULL, 0, thread_n == 1 ? SendMessage_thread_1 : SendMessage_thread_2, &wnd_event, 0, &tid);
+ ok(hthread != NULL, "CreateThread failed, error %d\n", GetLastError());
+ CloseHandle(hthread);
+
+ 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 */
+ for (;;)
+ {
+ ret = GetQueueStatus(QS_SENDMESSAGE);
+ if (ret == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE)) break;
+ Sleep(50);
+ }
+
+ ret = GetQueueStatus(QS_SENDMESSAGE|QS_POSTMESSAGE);
+todo_wine
+ ok(ret == MAKELONG(QS_POSTMESSAGE, QS_SENDMESSAGE|QS_POSTMESSAGE), "wrong status %08x\n", ret);
+
+ 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);
+ ok_sequence(send_message_1, "SendMessage from other thread 1", thread_n == 2);
+
+ /* intentionally yield */
+ MsgWaitForMultipleObjects(0, NULL, FALSE, 100, qs_all_input);
+
+ trace("main: call SendMessage\n");
+ SendMessageA(wnd_event.hwnd, WM_USER+4, 0, 0);
+ ok_sequence(send_message_2, "SendMessage from other thread 2", FALSE);
+
+ ret = GetQueueStatus(QS_SENDMESSAGE|QS_POSTMESSAGE);
+ ok(ret == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE|QS_POSTMESSAGE), "wrong status %08x\n", ret);
+
+ trace("main: call PeekMessage\n");
+ ok(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE), "PeekMessage should not fail\n");
+ ok(msg.message == WM_USER+1, "expected WM_USER+1, got %04x\n", msg.message);
+ DispatchMessageA(&msg);
+ ok_sequence(send_message_3, "SendMessage from other thread 3", thread_n == 2);
+
+ /* intentionally yield */
+ MsgWaitForMultipleObjects(0, NULL, FALSE, 100, qs_all_input);
+
+ ret = GetQueueStatus(QS_SENDMESSAGE|QS_POSTMESSAGE);
+ /* FIXME: remove once Wine is fixed */
+if (thread_n == 2) todo_wine
+ ok(ret == 0, "wrong status %08x\n", ret);
+else
+ ok(ret == 0, "wrong status %08x\n", ret);
+
+ trace("main: call PeekMessage\n");
+ ok(!PeekMessageA(&msg, 0, 0, 0, PM_REMOVE), "PeekMessage should fail\n");
+ ok_sequence(WmEmptySeq, "SendMessage from other thread 4", thread_n == 2);
+
+ ret = GetQueueStatus(QS_SENDMESSAGE|QS_POSTMESSAGE);
+ ok(ret == 0, "wrong status %08x\n", ret);
+
+ trace("main: call DestroyWindow\n");
+ DestroyWindow(msg.hwnd);
+
+ flush_events();
+ flush_sequence();
+}
+
static void init_funcs(void)
{
HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
@@ -14675,6 +14822,9 @@ START_TEST(msg)
pUnhookWinEvent = 0;
}
hEvent_hook = 0;
+
+ test_SendMessage_other_thread(1);
+ test_SendMessage_other_thread(2);
test_SetFocus();
test_SetParent();
test_PostMessage();
More information about the wine-cvs
mailing list