diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2015-05-25 14:13:18 -0400 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2015-05-27 09:34:04 -0400 |
commit | 4219b69145f13e95eadb5a666cb02b482bdd395b (patch) | |
tree | 5684a6cb585e60372d41144a4ae13eee8aaab710 /src | |
parent | 8a782f1699e2a59a3f3e91f6d7c35a3312b82b41 (diff) | |
download | rneovim-4219b69145f13e95eadb5a666cb02b482bdd395b.tar.gz rneovim-4219b69145f13e95eadb5a666cb02b482bdd395b.tar.bz2 rneovim-4219b69145f13e95eadb5a666cb02b482bdd395b.zip |
input: stream_set_blocking(): libuv impl
- Create a private libuv loop instead of re-using uv_default_loop(), to
avoid conflict[1] with existing watcher(s) on the fd.
- Expose the global "input" fd as a getter instead of a mutable global.
[1] .deps/build/src/libuv/src/unix/core.c:833:
uv__io_stop: Assertion `loop->watchers[w->fd] == w' failed.
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/globals.h | 3 | ||||
-rw-r--r-- | src/nvim/if_cscope.c | 2 | ||||
-rw-r--r-- | src/nvim/main.c | 6 | ||||
-rw-r--r-- | src/nvim/misc1.c | 2 | ||||
-rw-r--r-- | src/nvim/os/input.c | 13 | ||||
-rw-r--r-- | src/nvim/os/rstream.c | 5 | ||||
-rw-r--r-- | src/nvim/os/stream.c | 20 | ||||
-rw-r--r-- | src/nvim/os_unix.c | 1 |
8 files changed, 26 insertions, 26 deletions
diff --git a/src/nvim/globals.h b/src/nvim/globals.h index f012358404..1d93900a94 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -1217,9 +1217,6 @@ EXTERN char *ignoredp; // If a msgpack-rpc channel should be started over stdin/stdout EXTERN bool embedded_mode INIT(= false); -/// TTY from which input was gathered. -EXTERN int global_input_fd INIT(= 0); - /// Used to track the status of external functions. /// Currently only used for iconv(). typedef enum { diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index b3d61038c3..99926ecf16 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -820,7 +820,7 @@ err_closing: if (execl("/bin/sh", "sh", "-c", cmd, (char *)NULL) == -1) PERROR(_("cs_create_connection exec failed")); - stream_set_blocking(global_input_fd, true); //normalize stream (#2598) + stream_set_blocking(input_global_fd(), true); // normalize stream (#2598) exit(127); /* NOTREACHED */ default: /* parent. */ diff --git a/src/nvim/main.c b/src/nvim/main.c index 6ae96a7c69..4714de7c59 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -273,13 +273,13 @@ int main(int argc, char **argv) if (reading_input) { // One of the startup commands (arguments, sourced scripts or plugins) may // prompt the user, so start reading from a tty now. - global_input_fd = fileno(stdin); + int fd = fileno(stdin); if (!params.input_isatty || params.edit_type == EDIT_STDIN) { // Use stderr or stdout since stdin is not a tty and/or could be used to // read the "-" file (eg: cat file | nvim -) - global_input_fd = params.err_isatty ? fileno(stderr) : fileno(stdout); + fd = params.err_isatty ? fileno(stderr) : fileno(stdout); } - input_start_stdin(global_input_fd); + input_start_stdin(fd); } // open terminals when opening files that start with term:// diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index 13e5f273e0..0737caec5d 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -2679,6 +2679,7 @@ void preserve_exit(void) // Prevent repeated calls into this method. if (really_exiting) { + stream_set_blocking(input_global_fd(), true); //normalize stream (#2598) exit(2); } @@ -2699,7 +2700,6 @@ void preserve_exit(void) } ml_close_all(false); // close all memfiles, without deleting - stream_set_blocking(global_input_fd, true); //normalize stream (#2598) mch_errmsg("Vim: Finished.\n"); diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 5dcaee8304..f89ca4af95 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -35,6 +35,7 @@ typedef enum { static RStream *read_stream = NULL; static RBuffer *read_buffer = NULL, *input_buffer = NULL; static bool input_eof = false; +static int global_fd = 0; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/input.c.generated.h" @@ -47,12 +48,19 @@ void input_init(void) input_buffer = rbuffer_new(INPUT_BUFFER_SIZE + MAX_KEY_CODE_LEN); } +/// Gets the file from which input was gathered at startup. +int input_global_fd(void) +{ + return global_fd; +} + void input_start_stdin(int fd) { if (read_stream) { return; } + global_fd = fd; read_buffer = rbuffer_new(READ_BUFFER_SIZE); read_stream = rstream_new(read_cb, read_buffer, NULL); rstream_set_file(read_stream, fd); @@ -62,14 +70,9 @@ void input_start_stdin(int fd) void input_stop_stdin(void) { if (!read_stream) { - // In some cases (i.e. "nvim && read") where we do not explicitly play with - // std{in,out,err}, some other module/library nevertheless sets the stream - // to non-blocking; we still must "fix" the stream (#2598) in those cases. - stream_set_blocking(global_input_fd, true); // normalize stream (#2598) return; } - rstream_set_blocking(read_stream, true); // normalize stream (#2598) rstream_stop(read_stream); rstream_free(read_stream); read_stream = NULL; diff --git a/src/nvim/os/rstream.c b/src/nvim/os/rstream.c index 55bf89d768..702f282d53 100644 --- a/src/nvim/os/rstream.c +++ b/src/nvim/os/rstream.c @@ -297,11 +297,6 @@ void rstream_stop(RStream *rstream) } } -int rstream_set_blocking(RStream *rstream, bool blocking) -{ - return uv_stream_set_blocking(rstream->stream, blocking); -} - /// Returns the number of bytes ready for consumption in `rstream` size_t rstream_pending(RStream *rstream) { diff --git a/src/nvim/os/stream.c b/src/nvim/os/stream.c index 35cb41081d..0c448872c3 100644 --- a/src/nvim/os/stream.c +++ b/src/nvim/os/stream.c @@ -14,13 +14,17 @@ /// @return `0` on success, or `-errno` on failure. int stream_set_blocking(int fd, bool blocking) { - int flags = fcntl(fd, F_GETFL, 0); - int err = 0; - if (!blocking && !(flags & O_NONBLOCK)) { - err = fcntl(fd, F_SETFL, flags | O_NONBLOCK); - } else if (blocking && (flags & O_NONBLOCK)) { - err = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); - } - return err == -1 ? -errno : 0; + // Private loop to avoid conflict with existing watcher(s): + // uv__io_stop: Assertion `loop->watchers[w->fd] == w' failed. + uv_loop_t loop; + uv_pipe_t stream; + uv_loop_init(&loop); + uv_pipe_init(&loop, &stream, 0); + uv_pipe_open(&stream, fd); + int retval = uv_stream_set_blocking((uv_stream_t *)&stream, blocking); + uv_close((uv_handle_t *)&stream, NULL); + uv_run(&loop, UV_RUN_NOWAIT); // not necessary, but couldn't hurt. + uv_loop_close(&loop); + return retval; } diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index b2d5bae477..ccd0073db1 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -181,6 +181,7 @@ void mch_exit(int r) ml_close_all(TRUE); /* remove all memfiles */ event_teardown(); + stream_set_blocking(input_global_fd(), true); // normalize stream (#2598) #ifdef EXITFREE free_all_mem(); |