diff options
Diffstat (limited to 'src/nvim/os/job_private.h')
-rw-r--r-- | src/nvim/os/job_private.h | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/nvim/os/job_private.h b/src/nvim/os/job_private.h new file mode 100644 index 0000000000..1beaa1bd70 --- /dev/null +++ b/src/nvim/os/job_private.h @@ -0,0 +1,104 @@ +#ifndef NVIM_OS_JOB_PRIVATE_H +#define NVIM_OS_JOB_PRIVATE_H + +#include <stdlib.h> + +#include <uv.h> + +#include "nvim/os/rstream_defs.h" +#include "nvim/os/wstream_defs.h" +#include "nvim/os/pipe_process.h" +#include "nvim/os/shell.h" +#include "nvim/log.h" + +struct job { + // Job id the index in the job table plus one. + int id; + // Process id + int pid; + // Exit status code of the job process + int status; + // Number of references to the job. The job resources will only be freed by + // close_cb when this is 0 + int refcount; + // Time when job_stop was called for the job. + uint64_t stopped_time; + // If SIGTERM was already sent to the job(only send one before SIGKILL) + bool term_sent; + // Readable streams(std{out,err}) + RStream *out, *err; + // Writable stream(stdin) + WStream *in; + // Libuv streams representing stdin/stdout/stderr + uv_stream_t *proc_stdin, *proc_stdout, *proc_stderr; + // Extra data set by the process spawner + void *process; + // If process_close has been called on this job + bool closed; + // Startup options + JobOptions opts; +}; + +extern Job *table[]; +extern size_t stop_requests; +extern uv_timer_t job_stop_timer; + +static inline bool process_spawn(Job *job) +{ + return pipe_process_spawn(job); +} + +static inline void process_init(Job *job) +{ + pipe_process_init(job); +} + +static inline void process_close(Job *job) +{ + if (job->closed) { + return; + } + job->closed = true; + pipe_process_close(job); +} + +static inline void process_destroy(Job *job) +{ + pipe_process_destroy(job); +} + +static inline void job_exit_callback(Job *job) +{ + // Free the slot now, 'exit_cb' may want to start another job to replace + // this one + table[job->id - 1] = NULL; + + if (job->opts.exit_cb) { + // Invoke the exit callback + job->opts.exit_cb(job, job->opts.data); + } + + if (stop_requests && !--stop_requests) { + // Stop the timer if no more stop requests are pending + DLOG("Stopping job kill timer"); + uv_timer_stop(&job_stop_timer); + } +} + +static inline void job_decref(Job *job) +{ + if (--job->refcount == 0) { + // Invoke the exit_cb + job_exit_callback(job); + // Free all memory allocated for the job + free(job->proc_stdin->data); + free(job->proc_stdout->data); + free(job->proc_stderr->data); + shell_free_argv(job->opts.argv); + process_destroy(job); + free(job); + } +} + + +#endif // NVIM_OS_JOB_PRIVATE_H |