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:
parent
2aeaca6f7b
commit
6cfbee9f34
2 changed files with 22 additions and 18 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue