Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Unified Diff: base/message_loop/message_loop_unittest.cc

Issue 65173003: Kick the pump when allowing nestable tasks on a message loop (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: better test Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/message_loop/message_loop.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/message_loop/message_loop_unittest.cc
diff --git a/base/message_loop/message_loop_unittest.cc b/base/message_loop/message_loop_unittest.cc
index fe2d728fe408c8cd3baef46d692e920cee8e3571..f378db268936f716a12b8f40b8980641e1ff1c1a 100644
--- a/base/message_loop/message_loop_unittest.cc
+++ b/base/message_loop/message_loop_unittest.cc
@@ -23,6 +23,8 @@
#if defined(OS_WIN)
#include "base/message_loop/message_pump_win.h"
+#include "base/process/memory.h"
+#include "base/strings/string16.h"
#include "base/win/scoped_handle.h"
#endif
@@ -1080,4 +1082,92 @@ TEST(MessageLoopTest, IsType) {
EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_DEFAULT));
}
+#if defined(OS_WIN)
+void EmptyFunction() {}
+
+void PostMultipleTasks() {
+ MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&EmptyFunction));
+ MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&EmptyFunction));
+}
+
+static const int kSignalMsg = WM_USER + 2;
+
+void PostWindowsMessage(HWND message_hwnd) {
+ PostMessage(message_hwnd, kSignalMsg, 0, 2);
+}
+
+void EndTest(bool* did_run, HWND hwnd) {
+ *did_run = true;
+ PostMessage(hwnd, WM_CLOSE, 0, 0);
+}
+
+int kMyMessageFilterCode = 0x5002;
+
+LRESULT CALLBACK TestWndProcThunk(HWND hwnd, UINT message,
+ WPARAM wparam, LPARAM lparam) {
+ if (message == WM_CLOSE)
+ EXPECT_TRUE(DestroyWindow(hwnd));
+ if (message != kSignalMsg)
+ return DefWindowProc(hwnd, message, wparam, lparam);
+
+ switch (lparam) {
+ case 1:
+ // First, we post a task that will post multiple no-op tasks to make sure
+ // that the pump's incoming task queue does not become empty during the
+ // test.
+ MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&PostMultipleTasks));
+ // Next, we post a task that posts a windows message to trigger the second
+ // stage of the test.
+ MessageLoop::current()->PostTask(FROM_HERE,
+ base::Bind(&PostWindowsMessage, hwnd));
+ break;
+ case 2:
+ // Since we're about to enter a modal loop, tell the message loop that we
+ // intend to nest tasks.
+ MessageLoop::current()->SetNestableTasksAllowed(true);
+ bool did_run = false;
+ MessageLoop::current()->PostTask(FROM_HERE,
+ base::Bind(&EndTest, &did_run, hwnd));
+ // Run a nested windows-style message loop and verify that our task runs. If
+ // it doesn't, then we'll loop here until the test times out.
+ MSG msg;
+ while (GetMessage(&msg, 0, 0, 0)) {
+ if (!CallMsgFilter(&msg, kMyMessageFilterCode))
+ DispatchMessage(&msg);
+ // If this message is a WM_CLOSE, explicitly exit the modal loop. Posting
+ // a WM_QUIT should handle this, but unfortunately MessagePumpWin eats
+ // WM_QUIT messages even when running inside a modal loop.
+ if (msg.message == WM_CLOSE)
+ break;
+ }
+ EXPECT_TRUE(did_run);
+ MessageLoop::current()->Quit();
+ break;
+ }
+ return 0;
+}
+
+TEST(MessageLoopTest, AlwaysHaveUserMessageWhenNesting) {
+ MessageLoop loop(MessageLoop::TYPE_UI);
+ HINSTANCE instance = GetModuleFromAddress(&TestWndProcThunk);
+ WNDCLASSEX wc = {0};
+ wc.cbSize = sizeof(wc);
+ wc.lpfnWndProc = TestWndProcThunk;
+ wc.hInstance = instance;
+ wc.lpszClassName = L"MessageLoopTest_HWND";
+ ATOM atom = RegisterClassEx(&wc);
+ ASSERT_TRUE(atom);
+
+ HWND message_hwnd = CreateWindow(MAKEINTATOM(atom), 0, 0, 0, 0, 0, 0,
+ HWND_MESSAGE, 0, instance, 0);
+ ASSERT_TRUE(message_hwnd) << GetLastError();
+
+ ASSERT_TRUE(PostMessage(message_hwnd, kSignalMsg, 0, 1));
+
+ loop.Run();
+
+ ASSERT_TRUE(UnregisterClass(MAKEINTATOM(atom), instance));
+}
+#endif // defined(OS_WIN)
+
} // namespace base
« no previous file with comments | « base/message_loop/message_loop.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698