fix: avoid double free when destroying WebContents (#31104)
This commit is contained in:
parent
1a6a8f55af
commit
2360012cad
2 changed files with 18 additions and 2 deletions
|
@ -953,18 +953,31 @@ WebContents::~WebContents() {
|
||||||
// InspectableWebContents will be automatically destroyed.
|
// InspectableWebContents will be automatically destroyed.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebContents::DeleteThisIfAlive() {
|
||||||
|
// It is possible that the FirstWeakCallback has been called but the
|
||||||
|
// SecondWeakCallback has not, in this case the garbage collection of
|
||||||
|
// WebContents has already started and we should not |delete this|.
|
||||||
|
// Calling |GetWrapper| can detect this corner case.
|
||||||
|
auto* isolate = JavascriptEnvironment::GetIsolate();
|
||||||
|
v8::HandleScope scope(isolate);
|
||||||
|
v8::Local<v8::Object> wrapper;
|
||||||
|
if (!GetWrapper(isolate).ToLocal(&wrapper))
|
||||||
|
return;
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
void WebContents::Destroy() {
|
void WebContents::Destroy() {
|
||||||
// The content::WebContents should be destroyed asyncronously when possible
|
// The content::WebContents should be destroyed asyncronously when possible
|
||||||
// as user may choose to destroy WebContents during an event of it.
|
// as user may choose to destroy WebContents during an event of it.
|
||||||
if (Browser::Get()->is_shutting_down() || IsGuest() ||
|
if (Browser::Get()->is_shutting_down() || IsGuest() ||
|
||||||
type_ == Type::kBrowserView) {
|
type_ == Type::kBrowserView) {
|
||||||
delete this;
|
DeleteThisIfAlive();
|
||||||
} else {
|
} else {
|
||||||
base::PostTask(FROM_HERE, {content::BrowserThread::UI},
|
base::PostTask(FROM_HERE, {content::BrowserThread::UI},
|
||||||
base::BindOnce(
|
base::BindOnce(
|
||||||
[](base::WeakPtr<WebContents> contents) {
|
[](base::WeakPtr<WebContents> contents) {
|
||||||
if (contents)
|
if (contents)
|
||||||
delete contents.get();
|
contents->DeleteThisIfAlive();
|
||||||
},
|
},
|
||||||
GetWeakPtr()));
|
GetWeakPtr()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -451,6 +451,9 @@ class WebContents : public gin::Wrappable<WebContents>,
|
||||||
WebContents(v8::Isolate* isolate, const gin_helper::Dictionary& options);
|
WebContents(v8::Isolate* isolate, const gin_helper::Dictionary& options);
|
||||||
~WebContents() override;
|
~WebContents() override;
|
||||||
|
|
||||||
|
// Delete this if garbage collection has not started.
|
||||||
|
void DeleteThisIfAlive();
|
||||||
|
|
||||||
// Creates a InspectableWebContents object and takes ownership of
|
// Creates a InspectableWebContents object and takes ownership of
|
||||||
// |web_contents|.
|
// |web_contents|.
|
||||||
void InitWithWebContents(std::unique_ptr<content::WebContents> web_contents,
|
void InitWithWebContents(std::unique_ptr<content::WebContents> web_contents,
|
||||||
|
|
Loading…
Reference in a new issue