-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
[RDY] Refactor os_call_shell to use os_system #1365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
02e0370
to
ac599de
Compare
Would it be feasible to do a check at nvim exit time to see if all handles have been properly cleaned up (in debug mode at least)? |
ac599de
to
02c5d8b
Compare
I think the proper way to do this is to call But if you are talking about the first commit in this PR, the problem is much bigger: Due to the way we interact with libuv, leaving unclosed, stack-allocated handles can have really bad effects, such as a smashed stack. I detected the error caused by those unclosed handles whend debugging #1328 |
63efb1c
to
4274467
Compare
os_call_shell is now pretty close to os_system, the biggest difference is the logic to read/write from/to the current buffer. Could the performance improvement you noticed be the consequence of avoiding temporary file redirection when constructing the shell command? |
I'd be happy to .:) A little off topic, but #1241 is blocked on not being able to dup stderr and stdout to a single stream. Do you happen to know a way? (Not that I didn't already ask on the mailing list: https://groups.google.com/forum/#!topic/libuv/Q3espD5WWw8) |
Wouldn't that be the same as reading from both streams and appending to a single buffer? That is what os_system does. Maybe you can get a similar performance in #1241 by using |
I tested
Since (4) isn't portable, I figured (3) would be best, but
When I tested |
If that's the case, maybe we should simply leave os_call_shell as it is and use job_start directly? It has the advantage of skipping an additional process spawn(the shell) |
4274467
to
efb8e7c
Compare
Things like |
On second thought, it would be pretty trivial to just call |
Commit @709685b4612f4 removed the close_job_* calls when uv_spawn fails because of memory errors when trying to cleanup unitialized {R,W}Stream instances, but the uv_pipe_t instances must be closed because they are added to the event loop queue by previous `uv_pipe_init()` calls
Passing NULL as the callback for stdout/stderr will result in job_start ignoring stdout/stderr, respectively. A 'writable' boolean argument was also added, and when false `job_start` will ignore stdin. Also, refactor os_system to allow passing NULL as the `output` argument.
To follow our coding conventions
Use a timer to periodically compare the current HR time against the HR time of when `job_stop` was called. After 1 second, send SIGTERM, after 2 seconds, send SIGKILL. The timer is only active when there's at least one `job_stop` call pending.
efb8e7c
to
d878569
Compare
But of a late review, but apart from my one minor niggle noted in-place, this seems legit (and a good simplification). |
// close the input stream, let the process know that no more input is coming | ||
job_close_in(job); | ||
int status = job_wait(job, -1); | ||
status = job_wait(job, -1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can return early from job_wait()
(hitting CTRL-C) and there can still be waiting callbacks to system_data_cb()
.
If shell()
returns, the stack allocated buffer buf
becomes invalid, but the job callbacks can still try to use buf
.
Should close #473