From f3cc843755a6d638ada77dc31721aa53b3ff2364 Mon Sep 17 00:00:00 2001 From: Rui Abreu Ferreira Date: Tue, 28 Mar 2017 16:03:53 +0100 Subject: win: libuv_process_spawn(): special-case cmd.exe Disable CommandLineToArgvW-standard quoting for cmd.exe. libuv assumes spawned processes follow the convention expected by CommandLineToArgvW(). But cmd.exe is non-conformant, so for cmd.exe: - With system([]), the caller has full control (and responsibility) to quote arguments correctly. - With system(''), shell* options are used. libuv quoting is disabled if argv[0] is: - cmd.exe - cmd - $COMSPEC resolving to a path with filename cmd.exe Closes #6329 References #6387 --- src/nvim/event/libuv_process.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/nvim/event') diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index 3da0c386b4..ab69bea04c 100644 --- a/src/nvim/event/libuv_process.c +++ b/src/nvim/event/libuv_process.c @@ -8,6 +8,8 @@ #include "nvim/event/process.h" #include "nvim/event/libuv_process.h" #include "nvim/log.h" +#include "nvim/path.h" +#include "nvim/os/os.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/libuv_process.c.generated.h" @@ -24,6 +26,26 @@ int libuv_process_spawn(LibuvProcess *uvproc) if (proc->detach) { uvproc->uvopts.flags |= UV_PROCESS_DETACHED; } +#ifdef WIN32 + // libuv assumes spawned processes follow the convention from + // CommandLineToArgvW(), cmd.exe does not. Disable quoting since it will + // result in unexpected behaviour, the caller is left with the responsibility + // to quote arguments accordingly. system('') has shell* options for this. + // + // Disable quoting for cmd, cmd.exe and $COMSPEC with a cmd.exe filename + bool is_cmd = STRICMP(proc->argv[0], "cmd.exe") == 0 + || STRICMP(proc->argv[0], "cmd") == 0; + if (!is_cmd) { + const char_u *comspec = (char_u *)os_getenv("COMSPEC"); + const char_u *comspecshell = path_tail((char_u *)proc->argv[0]); + is_cmd = comspec != NULL && STRICMP(proc->argv[0], comspec) == 0 + && STRICMP("cmd.exe", (char *)comspecshell) == 0; + } + + if (is_cmd) { + uvproc->uvopts.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS; + } +#endif uvproc->uvopts.exit_cb = exit_cb; uvproc->uvopts.cwd = proc->cwd; uvproc->uvopts.env = NULL; -- cgit From 7c4e5dfd2722b8c25641cbbc66c5b0133d0e2f03 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 12 Apr 2017 01:35:17 +0200 Subject: win: os_shell_is_cmdexe() + tests --- src/nvim/event/libuv_process.c | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) (limited to 'src/nvim/event') diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index ab69bea04c..f5a41d151b 100644 --- a/src/nvim/event/libuv_process.c +++ b/src/nvim/event/libuv_process.c @@ -8,7 +8,6 @@ #include "nvim/event/process.h" #include "nvim/event/libuv_process.h" #include "nvim/log.h" -#include "nvim/path.h" #include "nvim/os/os.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -27,22 +26,9 @@ int libuv_process_spawn(LibuvProcess *uvproc) uvproc->uvopts.flags |= UV_PROCESS_DETACHED; } #ifdef WIN32 - // libuv assumes spawned processes follow the convention from - // CommandLineToArgvW(), cmd.exe does not. Disable quoting since it will - // result in unexpected behaviour, the caller is left with the responsibility - // to quote arguments accordingly. system('') has shell* options for this. - // - // Disable quoting for cmd, cmd.exe and $COMSPEC with a cmd.exe filename - bool is_cmd = STRICMP(proc->argv[0], "cmd.exe") == 0 - || STRICMP(proc->argv[0], "cmd") == 0; - if (!is_cmd) { - const char_u *comspec = (char_u *)os_getenv("COMSPEC"); - const char_u *comspecshell = path_tail((char_u *)proc->argv[0]); - is_cmd = comspec != NULL && STRICMP(proc->argv[0], comspec) == 0 - && STRICMP("cmd.exe", (char *)comspecshell) == 0; - } - - if (is_cmd) { + // 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 -- cgit From c2f3e361c52ec4e7149ea1d8c6a1202e0873da8e Mon Sep 17 00:00:00 2001 From: ZyX Date: Wed, 19 Apr 2017 19:11:50 +0300 Subject: *: Add comment to all C files --- src/nvim/event/libuv_process.c | 3 +++ src/nvim/event/loop.c | 3 +++ src/nvim/event/multiqueue.c | 3 +++ src/nvim/event/process.c | 3 +++ src/nvim/event/rstream.c | 3 +++ src/nvim/event/signal.c | 3 +++ src/nvim/event/socket.c | 3 +++ src/nvim/event/stream.c | 3 +++ src/nvim/event/time.c | 3 +++ src/nvim/event/wstream.c | 3 +++ 10 files changed, 30 insertions(+) (limited to 'src/nvim/event') diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index f5a41d151b..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 #include diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index 0e1775d01b..6963978581 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 #include diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index 79b4dd9458..a17bae31e3 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. // diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index 4429a65f92..ffda10a494 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 #include 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 #include #include 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 #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 #include 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 #include #include 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 #include 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 #include #include -- cgit From 3ea10077534cb1dcb1597ffcf85e601fa0c0e27b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 13 Mar 2017 15:02:37 +0100 Subject: api: nvim_get_mode() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Asynchronous API functions are served immediately, which means pending input could change the state of Nvim shortly after an async API function result is returned. nvim_get_mode() is different: - If RPCs are known to be blocked, it responds immediately (without flushing the input/event queue) - else it is handled just-in-time before waiting for input, after pending input was processed. This makes the result more reliable (but not perfect). Internally this is handled as a special case, but _semantically_ nothing has changed: API users never know when input flushes, so this internal special-case doesn't violate that. As far as API users are concerned, nvim_get_mode() is just another asynchronous API function. In all cases nvim_get_mode() never blocks for more than the time it takes to flush the input/event queue (~µs). Note: This doesn't address #6166; nvim_get_mode() will provoke #6166 if e.g. `d` is operator-pending. Closes #6159 --- src/nvim/event/loop.c | 3 +-- src/nvim/event/multiqueue.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) (limited to 'src/nvim/event') diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index 6963978581..c709ce9a1c 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -44,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 a17bae31e3..b144347fdb 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -55,6 +55,7 @@ #include "nvim/event/multiqueue.h" #include "nvim/memory.h" +#include "nvim/log.h" #include "nvim/os/time.h" typedef struct multiqueue_item MultiQueueItem; @@ -151,6 +152,40 @@ void multiqueue_process_events(MultiQueue *this) } } +void multiqueue_process_debug(MultiQueue *this) +{ + assert(this); + QUEUE *start = QUEUE_HEAD(&this->headtail); + QUEUE *cur = start; + // MultiQueue *start = this; + // MultiQueue *cur = start; + do { + MultiQueueItem *item = multiqueue_node_data(cur); + Event ev; + if (item->link) { + assert(!this->parent); + // 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)); + ev = child->data.item.event; + } else { + ev = item->data.item.event; + } + + // Event event = multiqueue_get(this); + // if (event.handler) { + // event.handler(event.argv); + // } + + ILOG("ev: priority=%d, handler=%p arg1=%s", ev.priority, ev.handler, + ev.argv ? ev.argv[0] : "(null)"); + + cur = cur->next; + } while (cur && cur != start); +} + /// Removes all events without processing them. void multiqueue_purge_events(MultiQueue *this) { -- cgit From acfd2a2a29ae852ecc965ca888eb5049400bf39d Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 14 Mar 2017 00:44:03 +0100 Subject: input.c: Process only safe events before blocking. Introduce multiqueue_process_priority() to process only events at or above a certain priority. --- src/nvim/event/defs.h | 5 +++ src/nvim/event/multiqueue.c | 93 ++++++++++++++++++++++++--------------------- src/nvim/event/multiqueue.h | 2 +- 3 files changed, 56 insertions(+), 44 deletions(-) (limited to 'src/nvim/event') diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h index e5335d9f25..509a3f8e7f 100644 --- a/src/nvim/event/defs.h +++ b/src/nvim/event/defs.h @@ -6,6 +6,11 @@ #define EVENT_HANDLER_MAX_ARGC 6 +typedef enum { + kEvPriorityNormal = 1, + kEvPriorityAsync = 2, // safe to run in any state +} EventPriority; + typedef void (*argv_callback)(void **argv); typedef struct message { int priority; diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index b144347fdb..a479a032f4 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -127,6 +127,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); @@ -145,45 +146,38 @@ 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); } } } -void multiqueue_process_debug(MultiQueue *this) +void multiqueue_process_priority(MultiQueue *this, int priority) { assert(this); QUEUE *start = QUEUE_HEAD(&this->headtail); - QUEUE *cur = start; - // MultiQueue *start = this; - // MultiQueue *cur = start; - do { + QUEUE *cur = start; + while (!multiqueue_empty(this)) { MultiQueueItem *item = multiqueue_node_data(cur); - Event ev; - if (item->link) { - assert(!this->parent); - // 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)); - ev = child->data.item.event; + assert(!item->link || !this->parent); // Only a parent queue has link-nodes + Event ev = multiqueueitem_get_event(item, false); + + if (ev.priority >= priority) { + if (ev.handler) { + ev.handler(ev.argv); + } + // Processed. Remove this item and get the new head. + (void)multiqueue_remove(this); + cur = QUEUE_HEAD(&this->headtail); } else { - ev = item->data.item.event; + // Not processed. Skip this item and get the next one. + cur = cur->next->next; + if (!cur || cur == start) { + break; + } } - - // Event event = multiqueue_get(this); - // if (event.handler) { - // event.handler(event.argv); - // } - - ILOG("ev: priority=%d, handler=%p arg1=%s", ev.priority, ev.handler, - ev.argv ? ev.argv[0] : "(null)"); - - cur = cur->next; - } while (cur && cur != start); + } } /// Removes all events without processing them. @@ -213,36 +207,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) @@ -250,6 +256,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..72145482aa 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(kEvPriorityNormal, h, __VA_ARGS__)); #ifdef INCLUDE_GENERATED_DECLARATIONS -- cgit From f17a8185191b778960953508a5bf9b5f95b0560c Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 27 Apr 2017 13:54:54 +0200 Subject: api/nvim_get_mode: Use child-queue instead of "priority". --- src/nvim/event/multiqueue.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nvim/event') diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index a479a032f4..66a261b554 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -55,7 +55,6 @@ #include "nvim/event/multiqueue.h" #include "nvim/memory.h" -#include "nvim/log.h" #include "nvim/os/time.h" typedef struct multiqueue_item MultiQueueItem; -- cgit From 8f59d1483934f91011b755406251136c406e77f6 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 27 Apr 2017 14:38:41 +0200 Subject: event: Remove "priority" concept. It was replaced by the "child queue" concept (MultiQueue). --- src/nvim/event/defs.h | 13 +++---------- src/nvim/event/multiqueue.c | 27 --------------------------- src/nvim/event/multiqueue.h | 2 +- 3 files changed, 4 insertions(+), 38 deletions(-) (limited to 'src/nvim/event') diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h index 509a3f8e7f..cc875d74b9 100644 --- a/src/nvim/event/defs.h +++ b/src/nvim/event/defs.h @@ -6,23 +6,16 @@ #define EVENT_HANDLER_MAX_ARGC 6 -typedef enum { - kEvPriorityNormal = 1, - kEvPriorityAsync = 2, // safe to run in any state -} EventPriority; - 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; \ @@ -34,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/multiqueue.c b/src/nvim/event/multiqueue.c index 66a261b554..ef9f3f1870 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -152,33 +152,6 @@ void multiqueue_process_events(MultiQueue *this) } } -void multiqueue_process_priority(MultiQueue *this, int priority) -{ - assert(this); - QUEUE *start = QUEUE_HEAD(&this->headtail); - QUEUE *cur = start; - while (!multiqueue_empty(this)) { - MultiQueueItem *item = multiqueue_node_data(cur); - assert(!item->link || !this->parent); // Only a parent queue has link-nodes - Event ev = multiqueueitem_get_event(item, false); - - if (ev.priority >= priority) { - if (ev.handler) { - ev.handler(ev.argv); - } - // Processed. Remove this item and get the new head. - (void)multiqueue_remove(this); - cur = QUEUE_HEAD(&this->headtail); - } else { - // Not processed. Skip this item and get the next one. - cur = cur->next->next; - if (!cur || cur == start) { - break; - } - } - } -} - /// Removes all events without processing them. void multiqueue_purge_events(MultiQueue *this) { diff --git a/src/nvim/event/multiqueue.h b/src/nvim/event/multiqueue.h index 72145482aa..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(kEvPriorityNormal, h, __VA_ARGS__)); + multiqueue_put_event(q, event_create(h, __VA_ARGS__)); #ifdef INCLUDE_GENERATED_DECLARATIONS -- cgit From 34c3f03013375817d3d089e685793290eded553a Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Thu, 4 May 2017 16:38:25 +0200 Subject: event/process.c: send SIGTERM directly (#6644) Send SIGTERM to processes directly, instead of waiting for ~1s. - removes TERM_TIMEOUT - changes KILL_TIMEOUT to milliseconds - removes Process.term_sent --- src/nvim/event/process.c | 22 ++++++++++------------ src/nvim/event/process.h | 3 +-- 2 files changed, 11 insertions(+), 14 deletions(-) (limited to 'src/nvim/event') diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index ffda10a494..6aab7d903c 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -20,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 { \ @@ -121,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); } } @@ -244,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); } } @@ -267,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 -- cgit