-
Notifications
You must be signed in to change notification settings - Fork 43
Kill with grace #367
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
base: safe-cleanup
Are you sure you want to change the base?
Kill with grace #367
Conversation
#include <signal.h> | ||
|
||
void R_init_sigtermignore(DllInfo *dll) { | ||
signal(SIGTERM, SIG_IGN); |
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.
Since I wrote this branch I've added sigterm handlers to px
in r-lib/ps#149. We could use this instead of this client lib for our unit tests by depending on the dev version of ps.
.grace = handle->cleanup_grace, | ||
.name = R_NilValue | ||
}; | ||
r_with_cleanup_context(c_processx_kill_data, &data); |
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.
I'd prefer to use the non-jumpy approach implemented in the ps PR, but I went for minimal changes here.
|
||
int *fds = malloc(sizeof(int) * 2); | ||
if (!fds) R_THROW_SYSTEM_ERROR("Allocating memory when waiting"); | ||
fds[0] = fds[1] = -1; | ||
r_call_on_exit(processx__wait_cleanup, fds); | ||
|
||
processx__block_sigchld(); | ||
sigset_t old; | ||
processx__block_sigchld_save(&old); |
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're now restoring the caller's signal mask on exit since this can now be called from C.
Otherwise a SIGPIPE may freeze an R process, like we saw in parallel testthat tests: r-lib/testthat#1819 Here the main proces is killed, but the worker processes are not, and when a worker process tries to send the test results to the main process, a `write()` on its pipe gets a `SIGPIPE. Unclear why, but the `SIGPIPE` sometimes causes a `SIGSEGV`, for which R tries to print the stack, but gets another `SIGSEGV`, and so on.
[ci ckip]
To please R CMD check :/
To see the rest of the printf format string warnings (#379).
Apparently, this only works correctly with HTTP/1.1, and fails with HTTP/2.
[ci skip]
To avoid a message from R6 at install and `load_all()` time.
Branched from #366.
Revive the
grace
argument in thekill()
method. We now first send aSIGTERM
, wait for a grace period, and only thenSIGKILL
To avoid a delay of
grace
seconds when the process terminates quickly, we poll for termination. This is supported by the same mechanism that is already implemented forwait()
. The routine is split into an R-facingprocessx_wait()
function and a C-facingc_processx_wait()
variant which is called by the kill implementation.The
new()
andrun()
methods of processes gain acleanup_grace
argument that is passed tokill()
andkill_tree()
on termination.