]> git.sesse.net Git - nageru/blobdiff - nageru/cef_capture.cpp
Fix a possible deadlock in CEF.
[nageru] / nageru / cef_capture.cpp
index 09c451fa2c7b6dff968f9b828e6c08f42a9d570b..952486158cdb67e19d604c6322af253d745b71ea 100644 (file)
@@ -97,8 +97,17 @@ void CEFCapture::resize(unsigned width, unsigned height)
        this->height = height;
 }
 
-void CEFCapture::request_new_frame()
+void CEFCapture::request_new_frame(bool ignore_if_locked)
 {
+       unique_lock<recursive_mutex> outer_lock(browser_mutex, defer_lock);
+       if (ignore_if_locked && !outer_lock.try_lock()) {
+               // If the caller is holding card_mutex, we need to abort here
+               // if we can't get browser_mutex, since otherwise, the UI thread
+               // might hold browser_mutex (blocking post_to_cef_ui_thread())
+               // and be waiting for card_mutex.
+               return;
+       }
+
        // By adding a delay, we make sure we don't get a new frame
        // delivered immediately (we probably already are on the UI thread),
        // where we couldn't really deal with it.
@@ -129,7 +138,7 @@ void CEFCapture::OnPaint(const void *buffer, int width, int height)
                // (CEF only sends OnPaint when there are actual changes,
                // so we need to do this explicitly, or we could be stuck on an
                // old frame forever if the image doesn't change.)
-               request_new_frame();
+               request_new_frame(/*ignore_if_locked=*/false);
                ++timecode;
        } else {
                assert(video_frame.size >= unsigned(width * height * 4));