From e7f9c69a5fe88a3fea5a7dc3ce71e7ed337bdbd7 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Tue, 13 Mar 2018 18:56:31 +0100 Subject: [PATCH] (Hopefully! :-) ) fix some deadlocks during CEF shutdown. --- cef_capture.cpp | 17 +++++++++++------ cef_capture.h | 4 +++- nageru_cef_app.cpp | 1 + 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/cef_capture.cpp b/cef_capture.cpp index e46f0c0..ff978f2 100644 --- a/cef_capture.cpp +++ b/cef_capture.cpp @@ -41,7 +41,7 @@ CEFCapture::~CEFCapture() void CEFCapture::post_to_cef_ui_thread(std::function &&func) { - lock_guard lock(browser_mutex); + lock_guard lock(browser_mutex); if (browser != nullptr) { CefPostTask(TID_UI, new CEFTaskAdapter(std::move(func))); } else { @@ -113,7 +113,10 @@ void CEFCapture::OnPaint(const void *buffer, int width, int height) // so we need to do this explicitly, or we could be stuck on an // old frame forever if the image doesn't change.) post_to_cef_ui_thread([this] { - browser->GetHost()->Invalidate(PET_VIEW); + lock_guard lock(browser_mutex); + if (browser != nullptr) { // Could happen if we are shutting down. + browser->GetHost()->Invalidate(PET_VIEW); + } }); ++timecode; } else { @@ -156,7 +159,7 @@ void CEFCapture::start_bm_capture() cef_app->initialize_cef(); CefPostTask(TID_UI, new CEFTaskAdapter([this]{ - lock_guard lock(browser_mutex); + lock_guard lock(browser_mutex); CefBrowserSettings browser_settings; browser_settings.web_security = cef_state_t::STATE_DISABLED; @@ -175,9 +178,11 @@ void CEFCapture::start_bm_capture() void CEFCapture::stop_dequeue_thread() { - lock_guard lock(browser_mutex); - cef_app->close_browser(browser); - browser = nullptr; // Or unref_cef() will be sad. + { + lock_guard lock(browser_mutex); + cef_app->close_browser(browser); + browser = nullptr; // Or unref_cef() will be sad. + } cef_app->unref_cef(); } diff --git a/cef_capture.h b/cef_capture.h index 311076e..9e231c9 100644 --- a/cef_capture.h +++ b/cef_capture.h @@ -189,7 +189,9 @@ private: std::string description, start_url; std::atomic max_fps{60}; - std::mutex browser_mutex; + // Needs to be recursive because the lambda in OnPaint could cause + // OnPaint itself to be called. + std::recursive_mutex browser_mutex; CefRefPtr browser; // Under . // Tasks waiting for to get ready. Under . diff --git a/nageru_cef_app.cpp b/nageru_cef_app.cpp index 2ddd816..2e64cee 100644 --- a/nageru_cef_app.cpp +++ b/nageru_cef_app.cpp @@ -38,6 +38,7 @@ void NageruCefApp::unref_cef() unique_lock lock(cef_mutex); if (--cef_thread_refcount == 0) { CefPostTask(TID_UI, new CEFTaskAdapter(&CefQuitMessageLoop)); + lock.unlock(); cef_thread.join(); } } -- 2.39.2