diff options
author | oni-link <knil.ino@gmail.com> | 2016-05-14 15:52:11 +0200 |
---|---|---|
committer | oni-link <knil.ino@gmail.com> | 2016-05-15 02:54:09 +0200 |
commit | bfc823f972f82d71848fbf66d247557904f873c5 (patch) | |
tree | a33ce7227c991c63e4b7b1179e574ea0ed6543a9 | |
parent | 14ea366f249ab5966019bfd399f8be5547c45569 (diff) | |
download | rneovim-bfc823f972f82d71848fbf66d247557904f873c5.tar.gz rneovim-bfc823f972f82d71848fbf66d247557904f873c5.tar.bz2 rneovim-bfc823f972f82d71848fbf66d247557904f873c5.zip |
fixup2: process.c: Prevent data loss for process output streams
The only data loss should be, if a process forked a child that keeps
sending data after the parent terminated.
While not in teardown mode we could keep reading child data, but then
`:!cmd` would block after `cmd` exited. In teardown mode we want to exit
nvim so we cannot keep reading child data.
-rw-r--r-- | src/nvim/event/process.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index 23a60c3052..8a84a71477 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -364,8 +364,10 @@ static void flush_stream(Process *proc, Stream *stream) size_t num_bytes = stream->num_bytes; // Poll for data and process the generated events. - loop_poll_events(&loop, 0); - queue_process_events(proc->events); + loop_poll_events(proc->loop, 0); + if (proc->events) { + queue_process_events(proc->events); + } // Stream can be closed if it is empty. if (num_bytes == stream->num_bytes) { @@ -400,11 +402,12 @@ static void on_process_exit(Process *proc) uv_timer_stop(&loop->children_kill_timer); } - // Process handles are closed in the next event loop tick. This is done to - // give libuv more time to read data from the OS after the process exits(If - // process_close_streams is called with data still in the OS buffer, we lose - // it) - CREATE_EVENT(proc->events, process_close_handles, 1, proc); + // Process has terminated, but there could still be data to be read from the + // OS. We are still in the libuv loop, so we cannot call code that polls for + // more data directly. Instead delay the reading after the libuv loop by + // queueing process_close_handles() as an event. + Queue *queue = proc->events ? proc->events : loop->events; + CREATE_EVENT(queue, process_close_handles, 1, proc); } static void on_process_stream_close(Stream *stream, void *data) |