mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
msgpack-rpc: Ensure stdio channels are properly closed
When stdio was closed, parse_msgpack was called with eof == true, with caused a free_channel call. To ensure the correct behavior for all types of channels, the close_channel must be called before free_channel.
This commit is contained in:
parent
b4ec764e8e
commit
d4f78127fb
@ -225,6 +225,10 @@ Object channel_send_call(uint64_t id,
|
||||
return NIL;
|
||||
}
|
||||
|
||||
if (channel->closed && !kv_size(channel->call_stack)) {
|
||||
free_channel(channel);
|
||||
}
|
||||
|
||||
return frame.result;
|
||||
}
|
||||
|
||||
@ -328,7 +332,7 @@ static void parse_msgpack(RStream *rstream, void *data, bool eof)
|
||||
Channel *channel = data;
|
||||
|
||||
if (eof) {
|
||||
goto end;
|
||||
close_channel(channel);
|
||||
}
|
||||
|
||||
size_t count = rstream_pending(rstream);
|
||||
@ -363,7 +367,7 @@ static void parse_msgpack(RStream *rstream, void *data, bool eof)
|
||||
}
|
||||
msgpack_unpacked_destroy(&unpacked);
|
||||
// Bail out from this event loop iteration
|
||||
goto end;
|
||||
return;
|
||||
}
|
||||
|
||||
handle_request(channel, &unpacked.data);
|
||||
@ -386,14 +390,6 @@ static void parse_msgpack(RStream *rstream, void *data, bool eof)
|
||||
"This error can also happen when deserializing "
|
||||
"an object with high level of nesting");
|
||||
}
|
||||
|
||||
end:
|
||||
if (eof && !channel->is_job && !kv_size(channel->call_stack)) {
|
||||
// The free_channel call is deferred for jobs because it's possible that
|
||||
// job_stderr will called after this. For non-job channels, this is the
|
||||
// last callback so it must be freed now.
|
||||
free_channel(channel);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_request(Channel *channel, msgpack_object *request)
|
||||
@ -569,6 +565,10 @@ static void unsubscribe(Channel *channel, char *event)
|
||||
/// free_channel later.
|
||||
static void close_channel(Channel *channel)
|
||||
{
|
||||
if (channel->closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
channel->closed = true;
|
||||
if (channel->is_job) {
|
||||
if (channel->data.job) {
|
||||
@ -577,10 +577,10 @@ static void close_channel(Channel *channel)
|
||||
} else {
|
||||
rstream_free(channel->data.streams.read);
|
||||
wstream_free(channel->data.streams.write);
|
||||
if (channel->data.streams.uv) {
|
||||
uv_close((uv_handle_t *)channel->data.streams.uv, close_cb);
|
||||
uv_handle_t *handle = (uv_handle_t *)channel->data.streams.uv;
|
||||
if (handle) {
|
||||
uv_close(handle, close_cb);
|
||||
} else {
|
||||
// When the stdin channel closes, it's time to go
|
||||
mch_exit(0);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user