Skip to content

Commit 6cfbee9

Browse files
authored
fix: uv_walk crash on web worker close (electron#24436)
* fix: uv_walk crash on web worker close * Use DCHECK_EQ
1 parent 2aeaca6 commit 6cfbee9

File tree

2 files changed

+23
-19
lines changed

2 files changed

+23
-19
lines changed

shell/common/node_bindings.cc

+21-19
Original file line numberDiff line numberDiff line change
@@ -96,25 +96,25 @@ ELECTRON_DESKTOP_CAPTURER_MODULE(V)
9696
namespace {
9797

9898
void stop_and_close_uv_loop(uv_loop_t* loop) {
99-
// Close any active handles
10099
uv_stop(loop);
101-
uv_walk(
102-
loop,
103-
[](uv_handle_t* handle, void*) {
104-
if (!uv_is_closing(handle)) {
105-
uv_close(handle, nullptr);
106-
}
107-
},
108-
nullptr);
109-
110-
// Run the loop to let it finish all the closing handles
111-
// NB: after uv_stop(), uv_run(UV_RUN_DEFAULT) returns 0 when that's done
112-
for (;;)
113-
if (!uv_run(loop, UV_RUN_DEFAULT))
114-
break;
100+
int error = uv_loop_close(loop);
101+
102+
while (error) {
103+
uv_run(loop, UV_RUN_DEFAULT);
104+
uv_stop(loop);
105+
uv_walk(
106+
loop,
107+
[](uv_handle_t* handle, void*) {
108+
if (!uv_is_closing(handle)) {
109+
uv_close(handle, nullptr);
110+
}
111+
},
112+
nullptr);
113+
uv_run(loop, UV_RUN_DEFAULT);
114+
error = uv_loop_close(loop);
115+
}
115116

116-
DCHECK(!uv_loop_alive(loop));
117-
uv_loop_close(loop);
117+
DCHECK_EQ(error, 0);
118118
}
119119

120120
bool g_is_initialized = false;
@@ -274,6 +274,7 @@ NodeBindings::~NodeBindings() {
274274
// Quit the embed thread.
275275
embed_closed_ = true;
276276
uv_sem_post(&embed_sem_);
277+
277278
WakeupEmbedThread();
278279

279280
// Wait for everything to be done.
@@ -284,7 +285,7 @@ NodeBindings::~NodeBindings() {
284285
uv_close(reinterpret_cast<uv_handle_t*>(&dummy_uv_handle_), nullptr);
285286

286287
// Clean up worker loop
287-
if (uv_loop_ == &worker_loop_)
288+
if (in_worker_loop())
288289
stop_and_close_uv_loop(uv_loop_);
289290
}
290291

@@ -501,7 +502,8 @@ void NodeBindings::WakeupMainThread() {
501502
}
502503

503504
void NodeBindings::WakeupEmbedThread() {
504-
uv_async_send(&dummy_uv_handle_);
505+
if (!in_worker_loop())
506+
uv_async_send(&dummy_uv_handle_);
505507
}
506508

507509
// static

shell/common/node_bindings.h

+2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ class NodeBindings {
5858

5959
uv_loop_t* uv_loop() const { return uv_loop_; }
6060

61+
bool in_worker_loop() const { return uv_loop_ == &worker_loop_; }
62+
6163
protected:
6264
explicit NodeBindings(BrowserEnvironment browser_env);
6365

0 commit comments

Comments
 (0)