mirror of
https://github.com/neovim/neovim.git
synced 2024-12-24 21:25:04 -07:00
loop_close: close all handles
- Move uv_stop(), it still causes a "leak" on exit somehow. - Tenatively restore `UV_RUN_DEFAULT`. It shouldn't hang since we clobber the handles via `uv_walk((h)=>uv_close(h))`. Although this still "leaks" on exit, it's faster than the 2-second timeout. fix #11820 fix #7376
This commit is contained in:
parent
d2730365ef
commit
47bd62c15c
@ -116,6 +116,15 @@ void loop_on_put(MultiQueue *queue, void *data)
|
|||||||
uv_stop(&loop->uv);
|
uv_stop(&loop->uv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(EXITFREE)
|
||||||
|
static void loop_walk_cb(uv_handle_t *handle, void *arg)
|
||||||
|
{
|
||||||
|
if (!uv_is_closing(handle)) {
|
||||||
|
uv_close(handle, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Closes `loop` and its handles, and frees its structures.
|
/// Closes `loop` and its handles, and frees its structures.
|
||||||
///
|
///
|
||||||
/// @param loop Loop to destroy
|
/// @param loop Loop to destroy
|
||||||
@ -125,21 +134,17 @@ void loop_on_put(MultiQueue *queue, void *data)
|
|||||||
bool loop_close(Loop *loop, bool wait)
|
bool loop_close(Loop *loop, bool wait)
|
||||||
{
|
{
|
||||||
bool rv = true;
|
bool rv = true;
|
||||||
// Loop won’t block for I/O after this.
|
|
||||||
uv_stop(&loop->uv);
|
|
||||||
// TODO(justinmk): Close all (lua/luv!) handles. But walk_cb() needs to call
|
|
||||||
// the resource-specific close-callbacks...
|
|
||||||
// uv_walk((h) => { if !uv_is_closing(h) { uv_close(h, …) } })
|
|
||||||
uv_mutex_destroy(&loop->mutex);
|
uv_mutex_destroy(&loop->mutex);
|
||||||
uv_close((uv_handle_t *)&loop->children_watcher, NULL);
|
uv_close((uv_handle_t *)&loop->children_watcher, NULL);
|
||||||
uv_close((uv_handle_t *)&loop->children_kill_timer, NULL);
|
uv_close((uv_handle_t *)&loop->children_kill_timer, NULL);
|
||||||
uv_close((uv_handle_t *)&loop->poll_timer, timer_close_cb);
|
uv_close((uv_handle_t *)&loop->poll_timer, timer_close_cb);
|
||||||
uv_close((uv_handle_t *)&loop->async, NULL);
|
uv_close((uv_handle_t *)&loop->async, NULL);
|
||||||
uint64_t start = wait ? os_hrtime() : 0;
|
uint64_t start = wait ? os_hrtime() : 0;
|
||||||
|
bool didstop = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
// Run the loop to tickle close-callbacks (which should then free memory).
|
// Run the loop to tickle close-callbacks (which should then free memory).
|
||||||
// Use UV_RUN_NOWAIT to avoid a hang. #11820
|
// Use UV_RUN_NOWAIT to avoid a hang. #11820
|
||||||
uv_run(&loop->uv, UV_RUN_NOWAIT);
|
uv_run(&loop->uv, didstop ? UV_RUN_DEFAULT : UV_RUN_NOWAIT);
|
||||||
if ((uv_loop_close(&loop->uv) != UV_EBUSY) || !wait) {
|
if ((uv_loop_close(&loop->uv) != UV_EBUSY) || !wait) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -151,6 +156,18 @@ bool loop_close(Loop *loop, bool wait)
|
|||||||
log_uv_handles(&loop->uv);
|
log_uv_handles(&loop->uv);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#if defined(EXITFREE)
|
||||||
|
(void)didstop;
|
||||||
|
#else
|
||||||
|
if (!didstop) {
|
||||||
|
// Loop won’t block for I/O after this.
|
||||||
|
uv_stop(&loop->uv);
|
||||||
|
// XXX: Close all (lua/luv!) handles. But loop_walk_cb() does not call
|
||||||
|
// resource-specific close-callbacks, so this leaks memory...
|
||||||
|
uv_walk(&loop->uv, loop_walk_cb, NULL);
|
||||||
|
didstop = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
multiqueue_free(loop->fast_events);
|
multiqueue_free(loop->fast_events);
|
||||||
multiqueue_free(loop->thread_events);
|
multiqueue_free(loop->thread_events);
|
||||||
|
Loading…
Reference in New Issue
Block a user