From 4057e6b56e7d35575d5b46aaebeee91be05c5782 Mon Sep 17 00:00:00 2001 From: Samuel Maddock Date: Thu, 18 Mar 2021 16:43:35 -0400 Subject: [PATCH] fix: DesktopCapturer gc'd prior to capture completion (#28273) desktopCapture.getSources() returns a promise which should resolve when capturing finishes. Internally it creates an instance of DesktopCapturer which is responsible for resolving or rejecting the promise. Between the time DesktopCapturer starts capturing frames and when it finishes, it's possible for its handle to be GC'd leading to it never resolving. These changes pin the instance of DesktopCapturer until it either finishes or errors. fixes #25595 --- shell/browser/api/electron_api_desktop_capturer.cc | 12 +++++++++++- shell/browser/api/electron_api_desktop_capturer.h | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/shell/browser/api/electron_api_desktop_capturer.cc b/shell/browser/api/electron_api_desktop_capturer.cc index a6b406afe05..00aded1a1be 100644 --- a/shell/browser/api/electron_api_desktop_capturer.cc +++ b/shell/browser/api/electron_api_desktop_capturer.cc @@ -162,6 +162,9 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) { v8::Locker locker(isolate); v8::HandleScope scope(isolate); gin_helper::CallMethod(this, "_onerror", "Failed to get sources."); + + Unpin(); + return; } @@ -195,12 +198,19 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) { v8::Locker locker(isolate); v8::HandleScope scope(isolate); gin_helper::CallMethod(this, "_onfinished", captured_sources_); + + Unpin(); } } // static gin::Handle DesktopCapturer::Create(v8::Isolate* isolate) { - return gin::CreateHandle(isolate, new DesktopCapturer(isolate)); + auto handle = gin::CreateHandle(isolate, new DesktopCapturer(isolate)); + + // Keep reference alive until capturing has finished. + handle->Pin(isolate); + + return handle; } gin::ObjectTemplateBuilder DesktopCapturer::GetObjectTemplateBuilder( diff --git a/shell/browser/api/electron_api_desktop_capturer.h b/shell/browser/api/electron_api_desktop_capturer.h index 3ef7c0bd1f1..9664836a0f3 100644 --- a/shell/browser/api/electron_api_desktop_capturer.h +++ b/shell/browser/api/electron_api_desktop_capturer.h @@ -13,12 +13,14 @@ #include "chrome/browser/media/webrtc/native_desktop_media_list.h" #include "gin/handle.h" #include "gin/wrappable.h" +#include "shell/common/gin_helper/pinnable.h" namespace electron { namespace api { class DesktopCapturer : public gin::Wrappable, + public gin_helper::Pinnable, public DesktopMediaListObserver { public: struct Source {