diff options
Diffstat (limited to 'src/nvim/event')
| -rw-r--r-- | src/nvim/event/defs.h | 8 | ||||
| -rw-r--r-- | src/nvim/event/libuv_process.c | 11 | ||||
| -rw-r--r-- | src/nvim/event/loop.c | 6 | ||||
| -rw-r--r-- | src/nvim/event/multiqueue.c | 51 | ||||
| -rw-r--r-- | src/nvim/event/multiqueue.h | 2 | ||||
| -rw-r--r-- | src/nvim/event/process.c | 25 | ||||
| -rw-r--r-- | src/nvim/event/process.h | 3 | ||||
| -rw-r--r-- | src/nvim/event/rstream.c | 3 | ||||
| -rw-r--r-- | src/nvim/event/signal.c | 3 | ||||
| -rw-r--r-- | src/nvim/event/socket.c | 3 | ||||
| -rw-r--r-- | src/nvim/event/stream.c | 3 | ||||
| -rw-r--r-- | src/nvim/event/time.c | 3 | ||||
| -rw-r--r-- | src/nvim/event/wstream.c | 3 |
13 files changed, 85 insertions, 39 deletions
diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h index e5335d9f25..cc875d74b9 100644 --- a/src/nvim/event/defs.h +++ b/src/nvim/event/defs.h @@ -8,16 +8,14 @@ typedef void (*argv_callback)(void **argv); typedef struct message { - int priority; argv_callback handler; void *argv[EVENT_HANDLER_MAX_ARGC]; } Event; typedef void(*event_scheduler)(Event event, void *data); -#define VA_EVENT_INIT(event, p, h, a) \ +#define VA_EVENT_INIT(event, h, a) \ do { \ assert(a <= EVENT_HANDLER_MAX_ARGC); \ - (event)->priority = p; \ (event)->handler = h; \ if (a) { \ va_list args; \ @@ -29,11 +27,11 @@ typedef void(*event_scheduler)(Event event, void *data); } \ } while (0) -static inline Event event_create(int priority, argv_callback cb, int argc, ...) +static inline Event event_create(argv_callback cb, int argc, ...) { assert(argc <= EVENT_HANDLER_MAX_ARGC); Event event; - VA_EVENT_INIT(&event, priority, cb, argc); + VA_EVENT_INIT(&event, cb, argc); return event; } diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index 3da0c386b4..3116adbde8 100644 --- a/src/nvim/event/libuv_process.c +++ b/src/nvim/event/libuv_process.c @@ -1,3 +1,6 @@ +// 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 <assert.h> #include <uv.h> @@ -8,6 +11,7 @@ #include "nvim/event/process.h" #include "nvim/event/libuv_process.h" #include "nvim/log.h" +#include "nvim/os/os.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/libuv_process.c.generated.h" @@ -24,6 +28,13 @@ int libuv_process_spawn(LibuvProcess *uvproc) if (proc->detach) { uvproc->uvopts.flags |= UV_PROCESS_DETACHED; } +#ifdef WIN32 + // libuv collapses the argv to a CommandLineToArgvW()-style string. cmd.exe + // expects a different syntax (must be prepared by the caller before now). + if (os_shell_is_cmdexe(proc->argv[0])) { + uvproc->uvopts.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS; + } +#endif uvproc->uvopts.exit_cb = exit_cb; uvproc->uvopts.cwd = proc->cwd; uvproc->uvopts.env = NULL; diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index 0e1775d01b..c709ce9a1c 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -1,3 +1,6 @@ +// 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 <stdint.h> @@ -41,8 +44,7 @@ void loop_poll_events(Loop *loop, int ms) // we do not block indefinitely for I/O. uv_timer_start(&loop->poll_timer, timer_cb, (uint64_t)ms, (uint64_t)ms); } else if (ms == 0) { - // For ms == 0, we need to do a non-blocking event poll by - // setting the run mode to UV_RUN_NOWAIT. + // For ms == 0, do a non-blocking event poll. mode = UV_RUN_NOWAIT; } diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index 79b4dd9458..ef9f3f1870 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -1,3 +1,6 @@ +// 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 + // Multi-level queue for selective async event processing. // Not threadsafe; access must be synchronized externally. // @@ -123,6 +126,7 @@ void multiqueue_free(MultiQueue *this) xfree(this); } +/// Removes the next item and returns its Event. Event multiqueue_get(MultiQueue *this) { return multiqueue_empty(this) ? NILEVENT : multiqueue_remove(this); @@ -141,7 +145,7 @@ void multiqueue_process_events(MultiQueue *this) { assert(this); while (!multiqueue_empty(this)) { - Event event = multiqueue_get(this); + Event event = multiqueue_remove(this); if (event.handler) { event.handler(event.argv); } @@ -175,36 +179,48 @@ size_t multiqueue_size(MultiQueue *this) return this->size; } -static Event multiqueue_remove(MultiQueue *this) +/// Gets an Event from an item. +/// +/// @param remove Remove the node from its queue, and free it. +static Event multiqueueitem_get_event(MultiQueueItem *item, bool remove) { - assert(!multiqueue_empty(this)); - QUEUE *h = QUEUE_HEAD(&this->headtail); - QUEUE_REMOVE(h); - MultiQueueItem *item = multiqueue_node_data(h); - Event rv; - + assert(item != NULL); + Event ev; if (item->link) { - assert(!this->parent); - // remove the next node in the linked queue + // get the next node in the linked queue MultiQueue *linked = item->data.queue; assert(!multiqueue_empty(linked)); MultiQueueItem *child = multiqueue_node_data(QUEUE_HEAD(&linked->headtail)); - QUEUE_REMOVE(&child->node); - rv = child->data.item.event; - xfree(child); + ev = child->data.item.event; + // remove the child node + if (remove) { + QUEUE_REMOVE(&child->node); + xfree(child); + } } else { - if (this->parent) { - // remove the corresponding link node in the parent queue + // remove the corresponding link node in the parent queue + if (remove && item->data.item.parent_item) { QUEUE_REMOVE(&item->data.item.parent_item->node); xfree(item->data.item.parent_item); + item->data.item.parent_item = NULL; } - rv = item->data.item.event; + ev = item->data.item.event; } + return ev; +} +static Event multiqueue_remove(MultiQueue *this) +{ + assert(!multiqueue_empty(this)); + QUEUE *h = QUEUE_HEAD(&this->headtail); + QUEUE_REMOVE(h); + MultiQueueItem *item = multiqueue_node_data(h); + assert(!item->link || !this->parent); // Only a parent queue has link-nodes + Event ev = multiqueueitem_get_event(item, true); this->size--; xfree(item); - return rv; + return ev; } static void multiqueue_push(MultiQueue *this, Event event) @@ -212,6 +228,7 @@ static void multiqueue_push(MultiQueue *this, Event event) MultiQueueItem *item = xmalloc(sizeof(MultiQueueItem)); item->link = false; item->data.item.event = event; + item->data.item.parent_item = NULL; QUEUE_INSERT_TAIL(&this->headtail, &item->node); if (this->parent) { // push link node to the parent queue diff --git a/src/nvim/event/multiqueue.h b/src/nvim/event/multiqueue.h index def6b95a10..a688107665 100644 --- a/src/nvim/event/multiqueue.h +++ b/src/nvim/event/multiqueue.h @@ -10,7 +10,7 @@ typedef struct multiqueue MultiQueue; typedef void (*put_callback)(MultiQueue *multiq, void *data); #define multiqueue_put(q, h, ...) \ - multiqueue_put_event(q, event_create(1, h, __VA_ARGS__)); + multiqueue_put_event(q, event_create(h, __VA_ARGS__)); #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index 4429a65f92..6aab7d903c 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -1,3 +1,6 @@ +// 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 <assert.h> #include <stdlib.h> @@ -17,9 +20,9 @@ # include "event/process.c.generated.h" #endif -// Time (ns) for a process to exit cleanly before we send TERM/KILL. -#define TERM_TIMEOUT 1000000000 -#define KILL_TIMEOUT (TERM_TIMEOUT * 2) +// Time for a process to exit cleanly before we send KILL. +#define KILL_TIMEOUT_MS 2000 +#define KILL_TIMEOUT_NS (KILL_TIMEOUT_MS * 1000000) #define CLOSE_PROC_STREAM(proc, stream) \ do { \ @@ -118,8 +121,6 @@ void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL // Close handles to process without killing it. CREATE_EVENT(loop->events, process_close_handles, 1, proc); } else { - uv_kill(proc->pid, SIGTERM); - proc->term_sent = true; process_stop(proc); } } @@ -241,12 +242,16 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL abort(); } + ILOG("Sending SIGTERM to pid %d", proc->pid); + uv_kill(proc->pid, SIGTERM); + Loop *loop = proc->loop; if (!loop->children_stop_requests++) { // When there's at least one stop request pending, start a timer that - // will periodically check if a signal should be send to a to the job + // will periodically check if a signal should be send to the job. DLOG("Starting job kill timer"); - uv_timer_start(&loop->children_kill_timer, children_kill_cb, 100, 100); + uv_timer_start(&loop->children_kill_timer, children_kill_cb, + KILL_TIMEOUT_MS, 100); } } @@ -264,11 +269,7 @@ static void children_kill_cb(uv_timer_t *handle) } uint64_t elapsed = now - proc->stopped_time; - if (!proc->term_sent && elapsed >= TERM_TIMEOUT) { - ILOG("Sending SIGTERM to pid %d", proc->pid); - uv_kill(proc->pid, SIGTERM); - proc->term_sent = true; - } else if (elapsed >= KILL_TIMEOUT) { + if (elapsed >= KILL_TIMEOUT_NS) { ILOG("Sending SIGKILL to pid %d", proc->pid); uv_kill(proc->pid, SIGKILL); } diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h index 26d70a5e6d..5c00e8e7ec 100644 --- a/src/nvim/event/process.h +++ b/src/nvim/event/process.h @@ -26,7 +26,7 @@ struct process { Stream *in, *out, *err; process_exit_cb cb; internal_process_cb internal_exit_cb, internal_close_cb; - bool closed, term_sent, detach; + bool closed, detach; MultiQueue *events; }; @@ -48,7 +48,6 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data) .err = NULL, .cb = NULL, .closed = false, - .term_sent = false, .internal_close_cb = NULL, .internal_exit_cb = NULL, .detach = false diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c index 2737dad305..854af474b2 100644 --- a/src/nvim/event/rstream.c +++ b/src/nvim/event/rstream.c @@ -1,3 +1,6 @@ +// 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 <assert.h> #include <stdint.h> #include <stdbool.h> diff --git a/src/nvim/event/signal.c b/src/nvim/event/signal.c index 11ce15a882..fec46da4ff 100644 --- a/src/nvim/event/signal.c +++ b/src/nvim/event/signal.c @@ -1,3 +1,6 @@ +// 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 <uv.h> #include "nvim/event/loop.h" diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c index 8f9327f3d4..e536d79a2a 100644 --- a/src/nvim/event/socket.c +++ b/src/nvim/event/socket.c @@ -1,3 +1,6 @@ +// 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 <assert.h> #include <stdint.h> diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index 26083c20f4..860a957b3e 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.c @@ -1,3 +1,6 @@ +// 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 <assert.h> #include <stdio.h> #include <stdbool.h> diff --git a/src/nvim/event/time.c b/src/nvim/event/time.c index 77260546db..80289c27d1 100644 --- a/src/nvim/event/time.c +++ b/src/nvim/event/time.c @@ -1,3 +1,6 @@ +// 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 <stdint.h> #include <uv.h> diff --git a/src/nvim/event/wstream.c b/src/nvim/event/wstream.c index fc7aad8eb9..f453e5898d 100644 --- a/src/nvim/event/wstream.c +++ b/src/nvim/event/wstream.c @@ -1,3 +1,6 @@ +// 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 <assert.h> #include <stdint.h> #include <stdbool.h> |