Don't run UI thread tasks after calling CefQuitMessageLoop

This avoids a situation where misbehaving clients may cause the
application to continue running indefinitely by posting new UI
thread tasks after calling CefQuitMessageLoop.
This commit is contained in:
Marshall Greenblatt 2023-07-11 09:41:47 +03:00
parent a8d552a01b
commit 75c3bf0480
3 changed files with 8 additions and 8 deletions

View File

@ -273,8 +273,8 @@ void CefMainRunner::Shutdown(base::OnceClosure shutdown_on_ui_thread,
void CefMainRunner::RunMessageLoop() { void CefMainRunner::RunMessageLoop() {
base::RunLoop run_loop; base::RunLoop run_loop;
DCHECK(quit_when_idle_callback_.is_null()); DCHECK(quit_callback_.is_null());
quit_when_idle_callback_ = run_loop.QuitWhenIdleClosure(); quit_callback_ = run_loop.QuitClosure();
main_delegate_->BeforeMainMessageLoopRun(&run_loop); main_delegate_->BeforeMainMessageLoopRun(&run_loop);
@ -283,11 +283,11 @@ void CefMainRunner::RunMessageLoop() {
} }
void CefMainRunner::QuitMessageLoop() { void CefMainRunner::QuitMessageLoop() {
if (!quit_when_idle_callback_.is_null()) { if (!quit_callback_.is_null()) {
if (main_delegate_->HandleMainMessageLoopQuit()) { if (main_delegate_->HandleMainMessageLoopQuit()) {
return; return;
} }
std::move(quit_when_idle_callback_).Run(); std::move(quit_callback_).Run();
} }
} }

View File

@ -89,7 +89,7 @@ class CefMainRunner : public CefMainRunnerHandler {
std::unique_ptr<CefUIThread> ui_thread_; std::unique_ptr<CefUIThread> ui_thread_;
// Used to quit the current base::RunLoop. // Used to quit the current base::RunLoop.
base::OnceClosure quit_when_idle_callback_; base::OnceClosure quit_callback_;
}; };
#endif // CEF_LIBCEF_BROWSER_MAIN_RUNNER_H_ #endif // CEF_LIBCEF_BROWSER_MAIN_RUNNER_H_

View File

@ -61,19 +61,19 @@ void ChromeMainRunnerDelegate::BeforeMainMessageLoopRun(
keep_alive_ = std::make_unique<ScopedKeepAlive>( keep_alive_ = std::make_unique<ScopedKeepAlive>(
KeepAliveOrigin::APP_CONTROLLER, KeepAliveRestartOption::DISABLED); KeepAliveOrigin::APP_CONTROLLER, KeepAliveRestartOption::DISABLED);
// The idle callback will be executed from BrowserProcessImpl::Unpin() via // The QuitClosure will be executed from BrowserProcessImpl::Unpin() via
// KeepAliveRegistry when the last ScopedKeepAlive is released. // KeepAliveRegistry when the last ScopedKeepAlive is released.
// ScopedKeepAlives are also held by Browser objects. // ScopedKeepAlives are also held by Browser objects.
DCHECK(g_browser_process); DCHECK(g_browser_process);
static_cast<BrowserProcessImpl*>(g_browser_process) static_cast<BrowserProcessImpl*>(g_browser_process)
->SetQuitClosure(run_loop->QuitWhenIdleClosure()); ->SetQuitClosure(run_loop->QuitClosure());
} }
bool ChromeMainRunnerDelegate::HandleMainMessageLoopQuit() { bool ChromeMainRunnerDelegate::HandleMainMessageLoopQuit() {
// May be called multiple times. See comments in RunMainMessageLoopBefore. // May be called multiple times. See comments in RunMainMessageLoopBefore.
keep_alive_.reset(); keep_alive_.reset();
// Cancel direct execution of the QuitWhenIdleClosure() in // Cancel direct execution of the QuitClosure() in
// CefMainRunner::QuitMessageLoop. We instead wait for all Chrome browser // CefMainRunner::QuitMessageLoop. We instead wait for all Chrome browser
// windows to exit. // windows to exit.
return true; return true;