Browse Source

fix: early GC of WebFrameMain instances (#27648)

Samuel Maddock 4 years ago
parent
commit
1bbfa934f0

+ 11 - 2
shell/browser/api/electron_api_web_frame_main.cc

@@ -57,6 +57,9 @@ WebFrameMain::~WebFrameMain() {
 }
 
 void WebFrameMain::MarkRenderFrameDisposed() {
+  if (render_frame_disposed_)
+    return;
+  Unpin();
   g_render_frame_map.Get().erase(render_frame_);
   render_frame_disposed_ = true;
 }
@@ -305,8 +308,14 @@ gin::Handle<WebFrameMain> WebFrameMain::From(v8::Isolate* isolate,
   if (rfh == nullptr)
     return gin::Handle<WebFrameMain>();
   auto* web_frame = FromRenderFrameHost(rfh);
-  auto handle = gin::CreateHandle(
-      isolate, web_frame == nullptr ? new WebFrameMain(rfh) : web_frame);
+  if (web_frame)
+    return gin::CreateHandle(isolate, web_frame);
+
+  auto handle = gin::CreateHandle(isolate, new WebFrameMain(rfh));
+
+  // Prevent garbage collection of frame until it has been deleted internally.
+  handle->Pin(isolate);
+
   return handle;
 }
 

+ 2 - 0
shell/browser/api/electron_api_web_frame_main.h

@@ -13,6 +13,7 @@
 #include "gin/handle.h"
 #include "gin/wrappable.h"
 #include "shell/common/gin_helper/constructible.h"
+#include "shell/common/gin_helper/pinnable.h"
 
 class GURL;
 
@@ -34,6 +35,7 @@ namespace api {
 
 // Bindings for accessing frames from the main process.
 class WebFrameMain : public gin::Wrappable<WebFrameMain>,
+                     public gin_helper::Pinnable<WebFrameMain>,
                      public gin_helper::Constructible<WebFrameMain> {
  public:
   // Create a new WebFrameMain and return the V8 wrapper of it.