Last active
December 16, 2015 09:19
-
-
Save aktau/5412466 to your computer and use it in GitHub Desktop.
waitpidTimeout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Wait (block) a maximum amount of time before forcefully killing a child (worker) and returning | |
* | |
* NOTE: this could interact badly if SIGCHLD is handled by a signal handler, such is the case | |
* with this particular codebase. The reason is that the wait() might not be triggered anymore | |
* because the PID in question was already waited on in the signal handler. | |
*/ | |
static void ctlWaitPidTimeout(pid_t worker_pid, useconds_t usec) { | |
TRACE("ctlWaitPidTimeout: waiting on %lu\n", (unsigned long) worker_pid); | |
/* create child that will time out */ | |
pid_t timeout_pid = fork(); | |
if (timeout_pid == 0) { | |
usleep(usec); | |
TRACE("ctlWaitPidTimeout: [WARNING] timing out!\n"); | |
_exit(0); | |
} | |
/* wait for either the timeout child to time out or the actual process that is being killed */ | |
pid_t exited_pid = wait(NULL); | |
/* whatever child just exited, kill the other one for good measure */ | |
if (exited_pid == worker_pid) { | |
TRACE("ctlWaitPidTimeout: worker pid exited, excellent\n"); | |
kill(timeout_pid, SIGKILL); | |
} | |
else { | |
TRACE("ctlWaitPidTimeout: timeout pid exited, will have to terminate worker the hard way\n"); | |
kill(worker_pid, SIGKILL); | |
} | |
/* wait for the child we just killed */ | |
wait(NULL); | |
TRACE("ctlWaitPidTimeout: timeout wait done\n"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment