aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2015-05-25 14:13:18 -0400
committerJustin M. Keyes <justinkz@gmail.com>2015-05-27 09:34:04 -0400
commit4219b69145f13e95eadb5a666cb02b482bdd395b (patch)
tree5684a6cb585e60372d41144a4ae13eee8aaab710
parent8a782f1699e2a59a3f3e91f6d7c35a3312b82b41 (diff)
downloadrneovim-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.
-rw-r--r--src/nvim/globals.h3
-rw-r--r--src/nvim/if_cscope.c2
-rw-r--r--src/nvim/main.c6
-rw-r--r--src/nvim/misc1.c2
-rw-r--r--src/nvim/os/input.c13
-rw-r--r--src/nvim/os/rstream.c5
-rw-r--r--src/nvim/os/stream.c20
-rw-r--r--src/nvim/os_unix.c1
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();