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
This commit is contained in:
Samuel Maddock 2021-03-18 16:43:35 -04:00 committed by GitHub
parent b52ccc9726
commit 4057e6b56e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 1 deletions

View file

@ -162,6 +162,9 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
v8::Locker locker(isolate); v8::Locker locker(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
gin_helper::CallMethod(this, "_onerror", "Failed to get sources."); gin_helper::CallMethod(this, "_onerror", "Failed to get sources.");
Unpin();
return; return;
} }
@ -195,12 +198,19 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
v8::Locker locker(isolate); v8::Locker locker(isolate);
v8::HandleScope scope(isolate); v8::HandleScope scope(isolate);
gin_helper::CallMethod(this, "_onfinished", captured_sources_); gin_helper::CallMethod(this, "_onfinished", captured_sources_);
Unpin();
} }
} }
// static // static
gin::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) { gin::Handle<DesktopCapturer> 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( gin::ObjectTemplateBuilder DesktopCapturer::GetObjectTemplateBuilder(

View file

@ -13,12 +13,14 @@
#include "chrome/browser/media/webrtc/native_desktop_media_list.h" #include "chrome/browser/media/webrtc/native_desktop_media_list.h"
#include "gin/handle.h" #include "gin/handle.h"
#include "gin/wrappable.h" #include "gin/wrappable.h"
#include "shell/common/gin_helper/pinnable.h"
namespace electron { namespace electron {
namespace api { namespace api {
class DesktopCapturer : public gin::Wrappable<DesktopCapturer>, class DesktopCapturer : public gin::Wrappable<DesktopCapturer>,
public gin_helper::Pinnable<DesktopCapturer>,
public DesktopMediaListObserver { public DesktopMediaListObserver {
public: public:
struct Source { struct Source {