fix: uv_walk crash on web worker close (#24436)

* fix: uv_walk crash on web worker close

* Use DCHECK_EQ
This commit is contained in:
Shelley Vohr 2020-07-08 11:00:43 -07:00 committed by GitHub
parent 2aeaca6f7b
commit 6cfbee9f34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 18 deletions

View file

@ -96,25 +96,25 @@ ELECTRON_DESKTOP_CAPTURER_MODULE(V)
namespace { namespace {
void stop_and_close_uv_loop(uv_loop_t* loop) { void stop_and_close_uv_loop(uv_loop_t* loop) {
// Close any active handles
uv_stop(loop); uv_stop(loop);
uv_walk( int error = uv_loop_close(loop);
loop,
[](uv_handle_t* handle, void*) {
if (!uv_is_closing(handle)) {
uv_close(handle, nullptr);
}
},
nullptr);
// Run the loop to let it finish all the closing handles while (error) {
// NB: after uv_stop(), uv_run(UV_RUN_DEFAULT) returns 0 when that's done uv_run(loop, UV_RUN_DEFAULT);
for (;;) uv_stop(loop);
if (!uv_run(loop, UV_RUN_DEFAULT)) uv_walk(
break; loop,
[](uv_handle_t* handle, void*) {
if (!uv_is_closing(handle)) {
uv_close(handle, nullptr);
}
},
nullptr);
uv_run(loop, UV_RUN_DEFAULT);
error = uv_loop_close(loop);
}
DCHECK(!uv_loop_alive(loop)); DCHECK_EQ(error, 0);
uv_loop_close(loop);
} }
bool g_is_initialized = false; bool g_is_initialized = false;
@ -274,6 +274,7 @@ NodeBindings::~NodeBindings() {
// Quit the embed thread. // Quit the embed thread.
embed_closed_ = true; embed_closed_ = true;
uv_sem_post(&embed_sem_); uv_sem_post(&embed_sem_);
WakeupEmbedThread(); WakeupEmbedThread();
// Wait for everything to be done. // Wait for everything to be done.
@ -284,7 +285,7 @@ NodeBindings::~NodeBindings() {
uv_close(reinterpret_cast<uv_handle_t*>(&dummy_uv_handle_), nullptr); uv_close(reinterpret_cast<uv_handle_t*>(&dummy_uv_handle_), nullptr);
// Clean up worker loop // Clean up worker loop
if (uv_loop_ == &worker_loop_) if (in_worker_loop())
stop_and_close_uv_loop(uv_loop_); stop_and_close_uv_loop(uv_loop_);
} }
@ -501,7 +502,8 @@ void NodeBindings::WakeupMainThread() {
} }
void NodeBindings::WakeupEmbedThread() { void NodeBindings::WakeupEmbedThread() {
uv_async_send(&dummy_uv_handle_); if (!in_worker_loop())
uv_async_send(&dummy_uv_handle_);
} }
// static // static

View file

@ -58,6 +58,8 @@ class NodeBindings {
uv_loop_t* uv_loop() const { return uv_loop_; } uv_loop_t* uv_loop() const { return uv_loop_; }
bool in_worker_loop() const { return uv_loop_ == &worker_loop_; }
protected: protected:
explicit NodeBindings(BrowserEnvironment browser_env); explicit NodeBindings(BrowserEnvironment browser_env);