aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/event/process.c
Commit message (Collapse)AuthorAge
* gcov: use __gcov_flush instead of __gcov_dump (#10260)Daniel Hahler2019-06-18
| | | | | | This restores missing coverage again. Move it to process_spawn in os/pty_process_unix.c, since it seems to break printargs-test on Windows/AppVeyor otherwise (#10248).
* Dump gcov coverage in process_spawn (#10230)Daniel Hahler2019-06-15
| | | Fixes https://github.com/neovim/neovim/pull/3926#issuecomment-502343527.
* Merge #8218 'Fix errors reported by PVS'Justin M. Keyes2018-04-27
|\ | | | | closes #4983
| * event/process: Silence PVS/V547: assuming stream->num_bytes changesZyX2018-04-17
| | | | | | | | Not familiar with the code, but I assume that loop_poll_events can actually change stream->num_bytes, so condition is not always false.
* | IO: shada should respect 'fsync' optionJustin M. Keyes2018-04-21
| | | | | | | | | | | | | | shada_write_file() is called on exit (:quit and friends), this can be very slow. Note: AFAICT Vim (do_viminfo()) does not appear to fsync() viminfo.
* | job-control: children_kill_cb(): do not check elapsed timeJustin M. Keyes2018-04-15
| | | | | | | | | | | | | | | | | | 1. Don't check elapsed time in children_kill_cb(), it's already implied by the start-time of the timer itself. 2. Restart timer from children_kill_cb() for PTY jobs, to send SIGKILL after SIGTERM. There is an edge case where SIGKILL might follow SIGTERM too quickly, if jobstop() is called near the 2-second timer window. But this edge case is not worth code complication.
* | job-control: one-shot timer instead of repeatingJustin M. Keyes2018-04-15
| | | | | | | | | | | | | | | | | | | | | | | | Before f31c26f1afb5 the timer was used to try SIGTERM *and* SIGKILL, so a repeating timer was needed. After f31c26f1afb5 process_stop() sends SIGTERM immediately, and the timer only sends SIGKILL. So we don't need a repeating timer. - Simplifies the logic: don't need to call uv_timer_stop() explicitly. - Avoids a problem: if process_stop() is called more than once in the 2-second window, the first on_process_exit() would call uv_timer_stop() which stops the timer for all stopped processes.
* | job-control: mitigate process-kill raceJustin M. Keyes2018-04-15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | children_kill_cb() is racey. One obvious problem is that process_close_handles() is *queued* by on_process_exit(), so when children_kill_cb() is invoked, the dead process might still be in the `loop->children` list. If the OS already reclaimed the dead PID, Nvim may try to SIGKILL it. Avoid that by checking `proc->status`. Vim doesn't have this problem because it doesn't attempt to kill processes that ignored SIGTERM after a timeout. closes #8269
* | loop: remove `children_stop_requests`Justin M. Keyes2018-04-15
|/ | | | | It serves no purpose because process_stop() is already guarded by `proc->stopped_time`.
* win: os_proc_tree_kill()Justin M. Keyes2018-03-16
| | | | | | | | XXX: comment at https://stackoverflow.com/q/1173342 : > Windows recycles PIDs quite fast, you have to be extra careful not > to kill unrelated processes. These APIs will report PPIDs for long > dead processes whose PIDs may have been recycled. Check the parent > start date to make sure it is related to the processes you spawned.
* jobs: child proc must have a separate process-groupJustin M. Keyes2018-03-16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | UV_PROCESS_DETACHED compels libuv:uv__process_child_init() to call setsid() in the child just after fork(). That ensures the process and its descendants are grouped in a separate session (and process group). The following jobstart() call correctly groups `sh` and `sleep` in a new session (and process-group), where `sh` is the "session leader" (and process-group leader): :call jobstart(['sh','-c','sleep 60']) SESN PGRP PID PPID Command 30383 30383 30383 3620 │ ├─ -bash 30383 31432 31432 30383 │ │ └─ nvim -u NORC 30383 31432 31433 30383 │ │ ├─ nvim -u NORC 8105 8105 8105 31432 │ │ └─ sh -c sleep 60 8105 8105 8106 8105 │ │ └─ sleep 60 closes #6530 ref: https://stackoverflow.com/q/1046933 ref: https://unix.stackexchange.com/a/404065 Helped-by: Marco Hinz <mh.codebro+github@gmail.com> Discussion ------------------------------------------------------------------------ On my linux box before this patch, the termclose_spec.lua:'kills job trapping SIGTERM' test indirectly causes cmake/busted to wait for 60s. That's because the test spawns a `sleep 60` descendant process which hangs around even after nvim exits: nvim killed the parent PID, but not PGID (process-group), so the grandchild "reparented" to init (PID 1). Session contains processes (and process-groups) which are logically part of the same "login session". Process-group is a set of logically/informally-related processes within a session; for example, shells assign a process group to each "job". Session IDs and PGIDs both have type pid_t (like PIDs). These OS-level mechanisms are, as usual, legacy accidents whose purpose is upheld by convention and folklore. We can use session-level grouping (setsid), or we could use process-group-level grouping (setpgid). Vim uses setsid() if available, otherwise setpgid(0,0). Windows ------------------------------------------------------------------------ UV_PROCESS_DETACHED on win32 sets CREATE_NEW_PROCESS_GROUP flag. But uv_kill() does not kill the process-group: https://github.com/nodejs/node/issues/3617 Ideas: - Set UV_PROCESS_DETACHED (CREATE_NEW_PROCESS_GROUP), then call GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, pid) - Maybe won't work because MSDN says "Only processes that share the same console as the calling process receive the signal." https://docs.microsoft.com/en-us/windows/console/generateconsolectrlevent But CREATE_NEW_PROCESS_GROUP creates a new console ... ref https://stackoverflow.com/q/1453520 - Group processes within a "job". libuv does that *globally* for non-detached processes: uv__init_global_job_handle. - Iterate through CreateToolhelp32Snapshot(). - https://stackoverflow.com/q/1173342 - Vim does this, see terminate_all()
* jobwait: return -2 on interrupt also with timeoutBjörn Linse2018-02-20
|
* channels: refactor jobwaitBjörn Linse2017-11-25
|
* channels: generalize jobclose()Björn Linse2017-11-25
|
* channels: allow bytes sockets and stdio, and buffered bytes outputBjörn Linse2017-11-24
|
* channels: refactorBjörn Linse2017-11-24
|
* process_close(): uv_unref() detached processes (#7539)Justin M. Keyes2017-11-12
| | | | | | | Doc for UV_PROCESS_DETACHED in uv.h mentions: > child process will still keep the parent's event loop alive unless > the parent process calls uv_unref() on the child's process handle. ref #3944
* log: some DEBUG-level stream loggingJustin M. Keyes2017-08-21
|
* jobstop/process_stop: send SIGTERM directlyDaniel Hahler2017-07-07
| | | | | This reverts the revert of #6644 (7c1a5d1d4), and handles it properly now (with tests).
* *: Fix all V641 errorsZyX2017-05-20
|
* Revert "event/process.c: send SIGTERM directly (#6644)"Justin M. Keyes2017-05-08
| | | | This reverts commit 34c3f03013375817d3d089e685793290eded553a.
* event/process.c: send SIGTERM directly (#6644)Daniel Hahler2017-05-04
| | | | | | | Send SIGTERM to processes directly, instead of waiting for ~1s. - removes TERM_TIMEOUT - changes KILL_TIMEOUT to milliseconds - removes Process.term_sent
* *: Add comment to all C filesZyX2017-04-19
|
* process_spawn: Return status code (#6075)Justin M. Keyes2017-02-09
|
* process_wait(): Avoid dereference after LOOP_PROCESS_EVENTS. (#5917)Justin M. Keyes2017-01-09
|
* event/multiqueue.c: Rename "queue" to "multiqueue".Justin M. Keyes2016-10-02
| | | | | | | | | | | | | | `lib/queue.h` implements a basic queue. `event/queue.c` implements a specialized data structure on top of lib/queue.h; it is not a "normal" queue. Rename the specialized multi-level queue implemented in event/queue.c to "multiqueue", to avoid confusion when reading the code. Before this change one can eventually notice that "macros (uppercase symbols) are for the normal queue, lowercase operations are for the multi-level queue", but that is unnecessary friction for new developers (or existing developers just visiting this part of the codebase).
* signal_init: Always unblock SIGCHLD. (#5243)Justin M. Keyes2016-08-29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Inherited signal mask may block SIGCHLD, which causes libuv to hang at epoll_wait. Closes #5230 Helped-by: Nicolas Hillegeer <nicolas@hillegeer.com> Helped-by: John Szakmeister <john@szakmeister.net> Note: the #pragma gymnastics are a workaround for broken system headers on macOS. signal.h: int sigaddset(sigset_t *, int); #define sigaddset(set, signo) (*(set) |= __sigbits(signo), 0) sys/_types/_sigset.h: typedef __darwin_sigset_t sigset_t; sys/_types.h: typedef __uint32_t __darwin_sigset_t; /* [???] signal set */ sigset_t is defined as unsigned int, but the sigaddset() ORs it with an int, mixing the types. So GCC generates a sign-conversion warning: sig.c:9:13: warning: implicit conversion changes signedness: 'int' to 'unsigned int' [-Wsign-conversion] (*(&s) |= __sigbits((sigset_t) 20), 0); ~~ ^~~~~~~~~~~~~~~~~~~~~~~~ 1 warning generated. System headers are normally ignored when the compiler generates warnings: https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html > GCC gives code found in system headers special treatment. All warnings, > other than those generated by ‘#warning’ (see Diagnostics), are suppressed > while GCC is processing a system header. Macros defined in a system header > are immune to a few warnings wherever they are expanded. This immunity is > granted on an ad-hoc basis, when we find that a warning generates lots of > false positives because of code in macros defined in system headers. Instead of the #pragma workaround, we could cast the sigset_t pointer: # if defined(__APPLE__) sigaddset((int *)&mask, SIGCHLD); # else sigaddset(&mask, SIGCHLD); # endif but that could break if the headers are later fixed.
* stream: set data together with callbackBjörn Linse2016-08-20
|
* Merge #4798 'process.c: Fix block in teardown'Justin M. Keyes2016-07-16
|\
| * process.c: Close events are processed too lateoni-link2016-05-28
| | | | | | | | | | | | Compiling with macro -DEXITFREE opens a code path on which the event loop is used after it was teared down, because not all close events were processed yet.
| * process.c: Fix a block when in teardown modeoni-link2016-05-28
| | | | | | | | | | | | | | nvim blocking can be tested with "nvim +te +'!xclip' +qa" By closing all handles for a pty process, we unblock the event loop if the process has not terminated yet.
* | Merge #4646 from oni-link/fix.issue.4569.3Justin M. Keyes2016-06-26
|\ \ | | | | | | Fix for missing output (#4569, ...)
| * | fixup2: process.c: Prevent data loss for process output streamsoni-link2016-05-15
| | | | | | | | | | | | | | | | | | | | | | | | The only data loss should be, if a process forked a child that keeps sending data after the parent terminated. While not in teardown mode we could keep reading child data, but then `:!cmd` would block after `cmd` exited. In teardown mode we want to exit nvim so we cannot keep reading child data.
| * | fixup: process.c: Prevent data loss for process output streamsoni-link2016-05-15
| | | | | | | | | | | | | | | | | | * Get system buffer size for upper data limit. Otherwise data loss if this buffer is too big. * Test whether teardown needs special handling.
| * | process.c: Prevent data loss for process output streamsoni-link2016-05-15
| |/ | | | | | | | | For a terminating process, it's output streams could be closed, before all data is read.
* | *: Fix errors from new linter checksZyX2016-06-11
| |
* | pty_process: split into plat-specific files (#3976)Rui Abreu Ferreira2016-06-04
|/
* *: Fix new linter errorsZyX2016-05-01
| | | | Originally there were 128 new errors, so I thought this is a good idea to fix all of them. Of course, this commit also fixes many suppressed errors.
* job control: don't kill PTY processes on exitBjörn Linse2016-01-20
| | | | These will automatically recieve SIGHUP on closing PTY master.
* job control: add 'detach' option to jobstartBjörn Linse2016-01-20
|
* Windows: avoid "uv_" naming conflicts. #3225Seth Jackson2015-08-27
|
* eval: Protect job callbacks from being redefinedThiago de Arruda2015-08-21
| | | | ref: #3188
* eval: Fix jobwait() to process multiple jobs concurrentlyThiago de Arruda2015-08-13
| | | | | | | | | | | | | The new event processing architecture changed `jobwait()` semantics: Only one job is processed at time since process_wait only focuses on one queue. This fixes the problem with a few changes: - Allow the event queue polled by `process_wait` to be overriden by a new argument. - Allow the parent queue to be overriden with `queue_replace_parent` - Create a temporary queue that serves as the parent for all jobs passed to `jobwait()`
* event: Refactor async event processingThiago de Arruda2015-08-13
| | | | | | | | | | - Improve the implementation of deferred/immediate events. - Use the new queue module to change how/when events are queued/processed by giving a private queue to each emitter. - Immediate events(which only exist to break uv_run recursion) are now represented in the `loop->fast_events` queue. - Events pushed to child queues are propagated to the event loop main queue and processed as K_EVENT keys.
* process: Pass loop reference during initializationThiago de Arruda2015-08-13
| | | | | Change the API so that it is passed to {uv,pty}_process_init instead of `process_spawn`.
* job: Replace by a better process abstraction layerThiago de Arruda2015-07-17
- New libuv/pty process abstraction with simplified API and no globals. - Remove nvim/os/job*. Jobs are now a concept that apply only to programs spawned by vimscript job* functions. - Refactor shell.c/channel.c to use the new module, which brings a number of advantages: - Simplified API, less code - No slots in the user job table are used - Not possible to acidentally receive data from vimscript - Implement job table in eval.c, which is now a hash table with unilimited job slots and unique job ids.