[desktopCapture Mac]reorder execution order in start/release processing
This cl is to move the RegisterRefreshAndMoveHandlers to be done on
capture thread, and reverse some execution order of releasing processing,
also remove a lock since the handler is on capturing thread too.
As we doubt the existing sequence may be the cause of a crash due to
race conditions at end of capture.
Bug: chromium:851883
Change-Id: I2254a69815144415424a77b4c82f150cfc369585
Reviewed-on: https://webrtc-review.googlesource.com/83822
Commit-Queue: Brave Yao <braveyao@webrtc.org>
Reviewed-by: Zijie He <zijiehe@chromium.org>
Cr-Commit-Position: refs/heads/master@{#23647}
diff --git a/modules/desktop_capture/mac/desktop_frame_provider.h b/modules/desktop_capture/mac/desktop_frame_provider.h
index b2abca8..7e17271 100644
--- a/modules/desktop_capture/mac/desktop_frame_provider.h
+++ b/modules/desktop_capture/mac/desktop_frame_provider.h
@@ -18,7 +18,7 @@
#include <memory>
#include "modules/desktop_capture/shared_desktop_frame.h"
-#include "rtc_base/synchronization/rw_lock_wrapper.h"
+#include "rtc_base/thread_checker.h"
#include "sdk/objc/Framework/Classes/Common/scoped_cftyperef.h"
namespace webrtc {
@@ -44,11 +44,9 @@
void Release();
private:
+ rtc::ThreadChecker thread_checker_;
const bool allow_iosurface_;
- // A lock protecting |io_surfaces_| across threads.
- const std::unique_ptr<RWLockWrapper> io_surfaces_lock_;
-
// Most recent IOSurface that contains a capture of matching display.
std::map<CGDirectDisplayID, std::unique_ptr<SharedDesktopFrame>> io_surfaces_;
diff --git a/modules/desktop_capture/mac/desktop_frame_provider.mm b/modules/desktop_capture/mac/desktop_frame_provider.mm
index 8417227..4234315 100644
--- a/modules/desktop_capture/mac/desktop_frame_provider.mm
+++ b/modules/desktop_capture/mac/desktop_frame_provider.mm
@@ -18,24 +18,25 @@
namespace webrtc {
DesktopFrameProvider::DesktopFrameProvider(bool allow_iosurface)
- : allow_iosurface_(allow_iosurface), io_surfaces_lock_(RWLockWrapper::CreateRWLock()) {}
+ : allow_iosurface_(allow_iosurface) {
+ thread_checker_.DetachFromThread();
+}
DesktopFrameProvider::~DesktopFrameProvider() {
- // Might be called from a thread which is not the one running the CGDisplayStream
- // handler. Indeed chromium's content destroys it from a dedicated thread.
+ RTC_DCHECK(thread_checker_.CalledOnValidThread());
+
Release();
}
std::unique_ptr<DesktopFrame> DesktopFrameProvider::TakeLatestFrameForDisplay(
CGDirectDisplayID display_id) {
+ RTC_DCHECK(thread_checker_.CalledOnValidThread());
+
if (!allow_iosurface_) {
// Regenerate a snapshot.
return DesktopFrameCGImage::CreateForDisplay(display_id);
}
- // Might be called from a thread which is not the one running the CGDisplayStream
- // handler. Indeed chromium's content uses a dedicates thread.
- WriteLockScoped scoped_io_surfaces_lock(*io_surfaces_lock_);
if (io_surfaces_[display_id]) {
return io_surfaces_[display_id]->Share();
}
@@ -45,6 +46,8 @@
void DesktopFrameProvider::InvalidateIOSurface(CGDirectDisplayID display_id,
rtc::ScopedCFTypeRef<IOSurfaceRef> io_surface) {
+ RTC_DCHECK(thread_checker_.CalledOnValidThread());
+
if (!allow_iosurface_) {
return;
}
@@ -52,19 +55,18 @@
std::unique_ptr<DesktopFrameIOSurface> desktop_frame_iosurface =
DesktopFrameIOSurface::Wrap(io_surface);
- // Call from the thread which runs the CGDisplayStream handler.
- WriteLockScoped scoped_io_surfaces_lock(*io_surfaces_lock_);
io_surfaces_[display_id] = desktop_frame_iosurface ?
SharedDesktopFrame::Wrap(std::move(desktop_frame_iosurface)) :
nullptr;
}
void DesktopFrameProvider::Release() {
+ RTC_DCHECK(thread_checker_.CalledOnValidThread());
+
if (!allow_iosurface_) {
return;
}
- WriteLockScoped scoped_io_surfaces_lock(*io_surfaces_lock_);
io_surfaces_.clear();
}
diff --git a/modules/desktop_capture/mac/screen_capturer_mac.mm b/modules/desktop_capture/mac/screen_capturer_mac.mm
index ebe77c8..ae6c47c 100644
--- a/modules/desktop_capture/mac/screen_capturer_mac.mm
+++ b/modules/desktop_capture/mac/screen_capturer_mac.mm
@@ -234,11 +234,7 @@
desktop_config_monitor_->Lock();
desktop_config_ = desktop_config_monitor_->desktop_configuration();
desktop_config_monitor_->Unlock();
- if (!RegisterRefreshAndMoveHandlers()) {
- RTC_LOG(LS_ERROR) << "Failed to register refresh and move handlers.";
- return false;
- }
- ScreenConfigurationChanged();
+
return true;
}
@@ -256,6 +252,13 @@
"webrtc", "ScreenCapturermac::Start", "target display id ", current_display_);
callback_ = callback;
+ // Start and operate CGDisplayStream handler all from capture thread.
+ if (!RegisterRefreshAndMoveHandlers()) {
+ RTC_LOG(LS_ERROR) << "Failed to register refresh and move handlers.";
+ callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
+ return;
+ }
+ ScreenConfigurationChanged();
}
void ScreenCapturerMac::CaptureFrame() {
@@ -273,7 +276,11 @@
// structures. Occasionally, the refresh and move handlers are lost when
// the screen mode changes, so re-register them here.
UnregisterRefreshAndMoveHandlers();
- RegisterRefreshAndMoveHandlers();
+ if (!RegisterRefreshAndMoveHandlers()) {
+ RTC_LOG(LS_ERROR) << "Failed to register refresh and move handlers.";
+ callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
+ return;
+ }
ScreenConfigurationChanged();
}
@@ -554,10 +561,9 @@
}
void ScreenCapturerMac::UnregisterRefreshAndMoveHandlers() {
+ display_stream_manager_->UnregisterActiveStreams();
// Release obsolete io surfaces.
desktop_frame_provider_.Release();
-
- display_stream_manager_->UnregisterActiveStreams();
}
void ScreenCapturerMac::ScreenRefresh(CGDirectDisplayID display_id,