Chrome Version : beginning of time?!
The following code will never return :
void SubPumpFunc(OnceClosure on_done) {
MessageLoopCurrent::ScopedNestableTaskAllower allow_nestable_tasks;
MSG msg;
while (::GetMessage(&msg, NULL, 0, 0)) {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
std::move(on_done).Run();
}
void Test() {
MessageLoop message_loop(MessageLoop::TYPE_UI);
RunLoop run_loop;
// Enter multiple levels of nested subpumps.
message_loop.task_runner()->PostTask(
FROM_HERE, BindOnce(&SubPumpFunc, run_loop.QuitClosure()));
message_loop.task_runner()->PostTask(
FROM_HERE, BindOnce(&SubPumpFunc, DoNothing::Once()));
// Quit the subsubpump (extra tasks ensure enough cycles to fully handle).
message_loop.task_runner()->PostTask(FROM_HERE,
BindOnce(&::PostQuitMessage, 0));
message_loop.task_runner()->PostTask(FROM_HERE, DoNothing());
message_loop.task_runner()->PostTask(FROM_HERE, DoNothing());
// Quit the subpump.
message_loop.task_runner()->PostTask(FROM_HERE,
BindOnce(&::PostQuitMessage, 0));
run_loop.Run();
}
the reason is that the first quit eats the kMsgHaveWork message when it reposts the WM_QUIT (ref. https://chromium-review.googlesource.com/c/chromium/src/+/1240158). As such, the subpump is no longer processing application tasks when it un-nests (and hence fails to post the second quit).
This was worse before https://chromium-review.googlesource.com/c/chromium/src/+/1240158 (the first quit would be taken away from either subpump and we would stay stuck forever); now at least the quits are handled, it's just that application tasks may be starved on resume if there were multiple layers of nesting subpumps.
Comment 1 by bugdroid1@chromium.org
, Sep 28