Skip to content

Commit be569cf

Browse files
authored
fix(core): uv_compat cleanup and fixes (#32458)
- split uv_compat into multiple files - move logic out of run_io into helpers - avoid holding references across callbacks to prevent violating aliasing - add a test suite, this goes through the same JsRuntime event loop infra as deno - fix shutdown not waiting for write queue to drain - use tokio shutdown instead of platform specific code - fix slightly incorrect phase ordering - fix some other issues found by claude review disclosure: large parts done by claude
1 parent 1e7a295 commit be569cf

File tree

5 files changed

+2640
-1045
lines changed

5 files changed

+2640
-1045
lines changed

libs/core/runtime/jsruntime.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,7 +2164,18 @@ impl JsRuntime {
21642164
Self::dispatch_rejections(scope, context_state, exception_state)?;
21652165
scope.perform_microtask_checkpoint();
21662166

2167-
// ===== Phase 3: I/O =====
2167+
// ===== Phase 3: Idle / Prepare =====
2168+
// In libuv: idle runs after pending callbacks, prepare runs right
2169+
// before I/O polling. Both must precede I/O.
2170+
if let Some(uv_inner_ptr) = context_state.uv_loop_inner.get() {
2171+
unsafe {
2172+
(*uv_inner_ptr).run_idle();
2173+
(*uv_inner_ptr).run_prepare();
2174+
};
2175+
}
2176+
scope.perform_microtask_checkpoint();
2177+
2178+
// ===== Phase 4: I/O =====
21682179
// Tight I/O loop: when run_io reads data and fires callbacks, the
21692180
// resulting JS work (nextTick/macrotasks from HTTP2 frame processing)
21702181
// may produce write calls. Drain those immediately and re-poll for
@@ -2185,16 +2196,8 @@ impl JsRuntime {
21852196
}
21862197
}
21872198

2188-
// ===== Phase 4: Idle / Prepare =====
2189-
if let Some(uv_inner_ptr) = context_state.uv_loop_inner.get() {
2190-
unsafe {
2191-
(*uv_inner_ptr).run_idle();
2192-
(*uv_inner_ptr).run_prepare();
2193-
};
2194-
}
2195-
scope.perform_microtask_checkpoint();
2196-
21972199
// ===== Phase 5: Check =====
2200+
// In libuv: check runs right after I/O polling.
21982201
if let Some(uv_inner_ptr) = context_state.uv_loop_inner.get() {
21992202
unsafe { (*uv_inner_ptr).run_check() };
22002203
}

0 commit comments

Comments
 (0)