mirror of
https://github.com/neovim/neovim
synced 2025-07-16 17:21:49 +00:00
loop_close: call uv_stop(), fix bug
- Call uv_stop(). - Restore `uv_loop_close` condition (braindead cosmetic change froma2efc9cf8b
that caused uv_loop_close *not* to be called if wait=false, sorry). Not doing `uv_walk(() => uv_close)`: see source comment for explanation. fix #11820 fix #7376 Q: Should we restore use of `UV_RUN_DEFAULT`/`UV_RUN_ONCE` (removed ina2efc9cf8b
)? A: The while-loop (hopefully) achieves the same purpose while avoiding a hang.
This commit is contained in:
@ -116,10 +116,20 @@ void loop_on_put(MultiQueue *queue, void *data)
|
|||||||
uv_stop(&loop->uv);
|
uv_stop(&loop->uv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Closes `loop` and its handles, and frees its structures.
|
||||||
|
///
|
||||||
|
/// @param loop Loop to destroy
|
||||||
|
/// @param wait Wait briefly for handles to deref
|
||||||
|
///
|
||||||
/// @returns false if the loop could not be closed gracefully
|
/// @returns false if the loop could not be closed gracefully
|
||||||
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);
|
||||||
@ -127,11 +137,14 @@ bool loop_close(Loop *loop, bool wait)
|
|||||||
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;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
// Run the loop to tickle close-callbacks (which should then free memory).
|
||||||
|
// Use UV_RUN_NOWAIT to avoid a hang. #11820
|
||||||
uv_run(&loop->uv, UV_RUN_NOWAIT);
|
uv_run(&loop->uv, UV_RUN_NOWAIT);
|
||||||
if (!wait || (uv_loop_close(&loop->uv) != UV_EBUSY)) {
|
if ((uv_loop_close(&loop->uv) != UV_EBUSY) || !wait) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (os_hrtime() - start >= 2 * 1000000000) {
|
uint64_t elapsed_s = (os_hrtime() - start) / 1000000000; // seconds
|
||||||
|
if (elapsed_s >= 2) {
|
||||||
// Some libuv resource was not correctly deref'd. Log and bail.
|
// Some libuv resource was not correctly deref'd. Log and bail.
|
||||||
rv = false;
|
rv = false;
|
||||||
ELOG("uv_loop_close() hang?");
|
ELOG("uv_loop_close() hang?");
|
||||||
|
Reference in New Issue
Block a user