diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:23:01 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:23:01 +0000 |
commit | 142d9041391780ac15b89886a54015fdc5c73995 (patch) | |
tree | 0f6b5cac1a60810a03f52826c9e67c9e2780b033 /src/nvim/event | |
parent | ad86b5db74922285699ab2a1dbb2ff20e6268a33 (diff) | |
parent | 3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff) | |
download | rneovim-142d9041391780ac15b89886a54015fdc5c73995.tar.gz rneovim-142d9041391780ac15b89886a54015fdc5c73995.tar.bz2 rneovim-142d9041391780ac15b89886a54015fdc5c73995.zip |
Merge remote-tracking branch 'upstream/master' into userreg
Diffstat (limited to 'src/nvim/event')
-rw-r--r-- | src/nvim/event/libuv_process.c | 17 | ||||
-rw-r--r-- | src/nvim/event/libuv_process.h | 3 | ||||
-rw-r--r-- | src/nvim/event/loop.c | 11 | ||||
-rw-r--r-- | src/nvim/event/loop.h | 4 | ||||
-rw-r--r-- | src/nvim/event/multiqueue.c | 6 | ||||
-rw-r--r-- | src/nvim/event/process.c | 44 | ||||
-rw-r--r-- | src/nvim/event/process.h | 14 | ||||
-rw-r--r-- | src/nvim/event/rstream.c | 9 | ||||
-rw-r--r-- | src/nvim/event/signal.c | 1 | ||||
-rw-r--r-- | src/nvim/event/signal.h | 3 | ||||
-rw-r--r-- | src/nvim/event/socket.c | 11 | ||||
-rw-r--r-- | src/nvim/event/socket.h | 3 | ||||
-rw-r--r-- | src/nvim/event/stream.c | 4 | ||||
-rw-r--r-- | src/nvim/event/stream.h | 6 | ||||
-rw-r--r-- | src/nvim/event/time.h | 4 | ||||
-rw-r--r-- | src/nvim/event/wstream.c | 6 | ||||
-rw-r--r-- | src/nvim/event/wstream.h | 3 |
17 files changed, 117 insertions, 32 deletions
diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index f012bacdd9..e528d21a71 100644 --- a/src/nvim/event/libuv_process.c +++ b/src/nvim/event/libuv_process.c @@ -2,16 +2,18 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <assert.h> +#include <stdint.h> #include <uv.h> +#include "nvim/eval/typval.h" #include "nvim/event/libuv_process.h" #include "nvim/event/loop.h" #include "nvim/event/process.h" -#include "nvim/event/rstream.h" -#include "nvim/event/wstream.h" +#include "nvim/event/stream.h" #include "nvim/log.h" #include "nvim/macros.h" #include "nvim/os/os.h" +#include "nvim/ui_client.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/libuv_process.c.generated.h" @@ -40,11 +42,19 @@ int libuv_process_spawn(LibuvProcess *uvproc) #endif uvproc->uvopts.exit_cb = exit_cb; uvproc->uvopts.cwd = proc->cwd; + uvproc->uvopts.stdio = uvproc->uvstdio; uvproc->uvopts.stdio_count = 3; uvproc->uvstdio[0].flags = UV_IGNORE; uvproc->uvstdio[1].flags = UV_IGNORE; uvproc->uvstdio[2].flags = UV_IGNORE; + + if (ui_client_forward_stdin) { + assert(UI_CLIENT_STDIN_FD == 3); + uvproc->uvopts.stdio_count = 4; + uvproc->uvstdio[3].data.fd = 0; + uvproc->uvstdio[3].flags = UV_INHERIT_FD; + } uvproc->uv.data = proc; if (proc->env) { @@ -77,6 +87,9 @@ int libuv_process_spawn(LibuvProcess *uvproc) uvproc->uvstdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; uvproc->uvstdio[2].data.stream = STRUCT_CAST(uv_stream_t, &proc->err.uv.pipe); + } else if (proc->fwd_err) { + uvproc->uvstdio[2].flags = UV_INHERIT_FD; + uvproc->uvstdio[2].data.fd = STDERR_FILENO; } int status; diff --git a/src/nvim/event/libuv_process.h b/src/nvim/event/libuv_process.h index 1132ce79ca..4472839944 100644 --- a/src/nvim/event/libuv_process.h +++ b/src/nvim/event/libuv_process.h @@ -3,13 +3,14 @@ #include <uv.h> +#include "nvim/event/loop.h" #include "nvim/event/process.h" typedef struct libuv_process { Process process; uv_process_t uv; uv_process_options_t uvopts; - uv_stdio_container_t uvstdio[3]; + uv_stdio_container_t uvstdio[4]; } LibuvProcess; static inline LibuvProcess libuv_process_init(Loop *loop, void *data) diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index 3329cbd574..ab2524c1a9 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -1,13 +1,16 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com -#include <stdarg.h> +#include <stdbool.h> #include <stdint.h> +#include <stdlib.h> #include <uv.h> +#include "nvim/event/defs.h" #include "nvim/event/loop.h" -#include "nvim/event/process.h" #include "nvim/log.h" +#include "nvim/memory.h" +#include "nvim/os/time.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/loop.c.generated.h" @@ -40,7 +43,7 @@ void loop_init(Loop *loop, void *data) /// @param once true: process at most one `Loop.uv` event. /// false: process until `ms` timeout (only has effect if `ms` > 0). /// @return true if `ms` > 0 and was reached -bool loop_uv_run(Loop *loop, int ms, bool once) +bool loop_uv_run(Loop *loop, int64_t ms, bool once) { if (loop->recursive++) { abort(); // Should not re-enter uv_run @@ -79,7 +82,7 @@ bool loop_uv_run(Loop *loop, int ms, bool once) /// > 0: timeout after `ms`. /// < 0: wait forever. /// @return true if `ms` > 0 and was reached -bool loop_poll_events(Loop *loop, int ms) +bool loop_poll_events(Loop *loop, int64_t ms) { bool timeout_expired = loop_uv_run(loop, ms, true); multiqueue_process_events(loop->fast_events); diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h index c0bcda40ce..b2265a726d 100644 --- a/src/nvim/event/loop.h +++ b/src/nvim/event/loop.h @@ -58,7 +58,7 @@ typedef struct loop { // Poll for events until a condition or timeout #define LOOP_PROCESS_EVENTS_UNTIL(loop, multiqueue, timeout, condition) \ do { \ - int remaining = timeout; \ + int64_t remaining = timeout; \ uint64_t before = (remaining > 0) ? os_hrtime() : 0; \ while (!(condition)) { \ LOOP_PROCESS_EVENTS(loop, multiqueue, remaining); \ @@ -66,7 +66,7 @@ typedef struct loop { break; \ } else if (remaining > 0) { \ uint64_t now = os_hrtime(); \ - remaining -= (int)((now - before) / 1000000); \ + remaining -= (int64_t)((now - before) / 1000000); \ before = now; \ if (remaining <= 0) { \ break; \ diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index 40d20033e0..e05084b656 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -46,14 +46,14 @@ // other sources and focus on a specific channel. #include <assert.h> -#include <stdarg.h> #include <stdbool.h> -#include <stdint.h> +#include <stddef.h> #include <uv.h> +#include "nvim/event/defs.h" #include "nvim/event/multiqueue.h" +#include "nvim/lib/queue.h" #include "nvim/memory.h" -#include "nvim/os/time.h" typedef struct multiqueue_item MultiQueueItem; struct multiqueue_item { diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index e029f778f6..1a524a56ca 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -2,20 +2,25 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <assert.h> +#include <inttypes.h> +#include <signal.h> #include <stdlib.h> #include <uv.h> +#include "klib/klist.h" #include "nvim/event/libuv_process.h" #include "nvim/event/loop.h" #include "nvim/event/process.h" -#include "nvim/event/rstream.h" -#include "nvim/event/wstream.h" #include "nvim/globals.h" #include "nvim/log.h" #include "nvim/macros.h" +#include "nvim/main.h" #include "nvim/os/process.h" #include "nvim/os/pty_process.h" #include "nvim/os/shell.h" +#include "nvim/os/time.h" +#include "nvim/rbuffer.h" +#include "nvim/ui_client.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/process.c.generated.h" @@ -32,10 +37,16 @@ void __gcov_flush(void); static bool process_is_tearing_down = false; +// Delay exit until handles are closed, to avoid deadlocks +static int exit_need_delay = 0; + /// @returns zero on success, or negative error code int process_spawn(Process *proc, bool in, bool out, bool err) FUNC_ATTR_NONNULL_ALL { + // forwarding stderr contradicts with processing it internally + assert(!(err && proc->fwd_err)); + if (in) { uv_pipe_init(&proc->loop->uv, &proc->in.uv.pipe, 0); } else { @@ -395,12 +406,41 @@ static void process_close_handles(void **argv) exit_need_delay--; } +static void exit_delay_cb(uv_timer_t *handle) +{ + uv_timer_stop(&main_loop.exit_delay_timer); + multiqueue_put(main_loop.fast_events, exit_event, 1, main_loop.exit_delay_timer.data); +} + +static void exit_event(void **argv) +{ + int status = (int)(intptr_t)argv[0]; + if (exit_need_delay) { + main_loop.exit_delay_timer.data = argv[0]; + uv_timer_start(&main_loop.exit_delay_timer, exit_delay_cb, 0, 0); + return; + } + + if (!exiting) { + os_exit(status); + } +} + +void exit_from_channel(int status) +{ + multiqueue_put(main_loop.fast_events, exit_event, 1, status); +} + static void on_process_exit(Process *proc) { Loop *loop = proc->loop; ILOG("exited: pid=%d status=%d stoptime=%" PRIu64, proc->pid, proc->status, proc->stopped_time); + if (ui_client_channel_id) { + exit_from_channel(proc->status); + } + // 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 diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h index 30254bfe07..e0057faffb 100644 --- a/src/nvim/event/process.h +++ b/src/nvim/event/process.h @@ -1,11 +1,20 @@ #ifndef NVIM_EVENT_PROCESS_H #define NVIM_EVENT_PROCESS_H +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + #include "nvim/eval/typval.h" +#include "nvim/eval/typval_defs.h" #include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/event/rstream.h" +#include "nvim/event/stream.h" #include "nvim/event/wstream.h" +struct process; + typedef enum { kProcessTypeUv, kProcessTypePty, @@ -29,7 +38,7 @@ struct process { /// Exit handler. If set, user must call process_free(). process_exit_cb cb; internal_process_cb internal_exit_cb, internal_close_cb; - bool closed, detach, overlapped; + bool closed, detach, overlapped, fwd_err; MultiQueue *events; }; @@ -53,7 +62,8 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data) .closed = false, .internal_close_cb = NULL, .internal_exit_cb = NULL, - .detach = false + .detach = false, + .fwd_err = false, }; } diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c index 2847788ef8..a88d62fd6b 100644 --- a/src/nvim/event/rstream.c +++ b/src/nvim/event/rstream.c @@ -3,17 +3,18 @@ #include <assert.h> #include <stdbool.h> +#include <stddef.h> #include <stdint.h> -#include <stdlib.h> #include <uv.h> -#include "nvim/ascii.h" #include "nvim/event/loop.h" #include "nvim/event/rstream.h" +#include "nvim/event/stream.h" #include "nvim/log.h" +#include "nvim/macros.h" #include "nvim/main.h" -#include "nvim/memory.h" -#include "nvim/vim.h" +#include "nvim/os/os_defs.h" +#include "nvim/rbuffer.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/rstream.c.generated.h" diff --git a/src/nvim/event/signal.c b/src/nvim/event/signal.c index 4a45a2ec2f..8256ca2091 100644 --- a/src/nvim/event/signal.c +++ b/src/nvim/event/signal.c @@ -1,6 +1,7 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +#include <stddef.h> #include <uv.h> #include "nvim/event/loop.h" diff --git a/src/nvim/event/signal.h b/src/nvim/event/signal.h index 7fe352edef..f9adf62c20 100644 --- a/src/nvim/event/signal.h +++ b/src/nvim/event/signal.h @@ -4,6 +4,9 @@ #include <uv.h> #include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" + +struct signal_watcher; typedef struct signal_watcher SignalWatcher; typedef void (*signal_cb)(SignalWatcher *watcher, int signum, void *data); diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c index 9ca3dcc276..10756015ad 100644 --- a/src/nvim/event/socket.c +++ b/src/nvim/event/socket.c @@ -2,23 +2,24 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <assert.h> -#include <stdint.h> +#include <inttypes.h> +#include <stdbool.h> +#include <stdio.h> +#include <string.h> #include <uv.h> #include "nvim/ascii.h" #include "nvim/charset.h" #include "nvim/event/loop.h" -#include "nvim/event/rstream.h" #include "nvim/event/socket.h" -#include "nvim/event/wstream.h" +#include "nvim/event/stream.h" +#include "nvim/gettext.h" #include "nvim/log.h" #include "nvim/macros.h" #include "nvim/main.h" #include "nvim/memory.h" #include "nvim/os/os.h" #include "nvim/path.h" -#include "nvim/strings.h" -#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/socket.c.generated.h" diff --git a/src/nvim/event/socket.h b/src/nvim/event/socket.h index d30ae45502..c6fcdec4bb 100644 --- a/src/nvim/event/socket.h +++ b/src/nvim/event/socket.h @@ -4,9 +4,12 @@ #include <uv.h> #include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/event/rstream.h" #include "nvim/event/wstream.h" +struct socket_watcher; + #define ADDRESS_MAX_SIZE 256 typedef struct socket_watcher SocketWatcher; diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index bfb7a551b9..0a4918636a 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.c @@ -3,9 +3,11 @@ #include <assert.h> #include <stdbool.h> -#include <stdio.h> +#include <stddef.h> #include <uv.h> +#include <uv/version.h> +#include "nvim/event/loop.h" #include "nvim/event/stream.h" #include "nvim/log.h" #include "nvim/macros.h" diff --git a/src/nvim/event/stream.h b/src/nvim/event/stream.h index b580d3c33d..33d2d6e775 100644 --- a/src/nvim/event/stream.h +++ b/src/nvim/event/stream.h @@ -6,8 +6,11 @@ #include <uv.h> #include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/rbuffer.h" +struct stream; + typedef struct stream Stream; /// Type of function called when the Stream buffer is filled with data /// @@ -16,8 +19,7 @@ typedef struct stream Stream; /// @param count Number of bytes that was read. /// @param data User-defined data /// @param eof If the stream reached EOF. -typedef void (*stream_read_cb)(Stream *stream, RBuffer *buf, size_t count, - void *data, bool eof); +typedef void (*stream_read_cb)(Stream *stream, RBuffer *buf, size_t count, void *data, bool eof); /// Type of function called when the Stream has information about a write /// request. diff --git a/src/nvim/event/time.h b/src/nvim/event/time.h index a6de89ad6e..e84488fdd6 100644 --- a/src/nvim/event/time.h +++ b/src/nvim/event/time.h @@ -1,9 +1,13 @@ #ifndef NVIM_EVENT_TIME_H #define NVIM_EVENT_TIME_H +#include <stdbool.h> #include <uv.h> #include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" + +struct time_watcher; typedef struct time_watcher TimeWatcher; typedef void (*time_cb)(TimeWatcher *watcher, void *data); diff --git a/src/nvim/event/wstream.c b/src/nvim/event/wstream.c index d81ffa5c15..65391ba5cf 100644 --- a/src/nvim/event/wstream.c +++ b/src/nvim/event/wstream.c @@ -3,15 +3,13 @@ #include <assert.h> #include <stdbool.h> -#include <stdint.h> -#include <stdlib.h> #include <uv.h> #include "nvim/event/loop.h" +#include "nvim/event/stream.h" #include "nvim/event/wstream.h" -#include "nvim/log.h" +#include "nvim/macros.h" #include "nvim/memory.h" -#include "nvim/vim.h" #define DEFAULT_MAXMEM 1024 * 1024 * 2000 diff --git a/src/nvim/event/wstream.h b/src/nvim/event/wstream.h index d599d29913..ef1311c619 100644 --- a/src/nvim/event/wstream.h +++ b/src/nvim/event/wstream.h @@ -2,12 +2,15 @@ #define NVIM_EVENT_WSTREAM_H #include <stdbool.h> +#include <stddef.h> #include <stdint.h> #include <uv.h> #include "nvim/event/loop.h" #include "nvim/event/stream.h" +struct wbuffer; + typedef struct wbuffer WBuffer; typedef void (*wbuffer_data_finalizer)(void *data); |