job: Simplify job_teardown function

Remove the current teardown logic and reuse the job top timers with
event_poll_until all jobs exit or are killed.
This commit is contained in:
Thiago de Arruda 2014-11-01 10:52:58 -03:00
parent 48847fbafc
commit 0ffeb140a4

View File

@ -88,51 +88,18 @@ void job_init(void)
/// Releases job control resources and terminates running jobs /// Releases job control resources and terminates running jobs
void job_teardown(void) void job_teardown(void)
{ {
// 20 tries will give processes about 1 sec to exit cleanly // Stop all jobs
uint32_t remaining_tries = 20; for (int i = 0; i < MAX_RUNNING_JOBS; i++) {
bool all_dead = true; Job *job;
int i;
Job *job;
// Politely ask each job to terminate
for (i = 0; i < MAX_RUNNING_JOBS; i++) {
if ((job = table[i]) != NULL) { if ((job = table[i]) != NULL) {
all_dead = false; job_stop(job);
uv_process_kill(&job->proc, SIGTERM);
} }
} }
if (all_dead) { // Wait until all jobs are closed
return; event_poll_until(-1, !stop_requests);
} // Close the timer
uv_close((uv_handle_t *)&job_stop_timer, NULL);
os_delay(10, 0);
// Right now any exited process are zombies waiting for us to acknowledge
// their status with `wait` or handling SIGCHLD. libuv does that
// automatically (and then calls `exit_cb`) but we have to give it a chance
// by running the loop one more time
event_poll(0);
// Prepare to start shooting
for (i = 0; i < MAX_RUNNING_JOBS; i++) {
job = table[i];
// Still alive
while (job && is_alive(job) && remaining_tries--) {
os_delay(50, 0);
// Acknowledge child exits
event_poll(0);
// It's possible that the event_poll call removed the job from the table,
// reset 'job' so the next iteration won't run in that case.
job = table[i];
}
if (job && is_alive(job)) {
uv_process_kill(&job->proc, SIGKILL);
}
}
// Last run to ensure all children were removed
event_poll(0);
} }
/// Tries to start a new job. /// Tries to start a new job.
@ -427,18 +394,13 @@ static void job_exit_callback(Job *job)
job->exit_cb(job, job->data); job->exit_cb(job, job->data);
} }
if (!--stop_requests) { if (stop_requests && !--stop_requests) {
// Stop the timer if no more stop requests are pending // Stop the timer if no more stop requests are pending
DLOG("Stopping job kill timer"); DLOG("Stopping job kill timer");
uv_timer_stop(&job_stop_timer); uv_timer_stop(&job_stop_timer);
} }
} }
static bool is_alive(Job *job)
{
return uv_process_kill(&job->proc, 0) == 0;
}
/// Iterates the table, sending SIGTERM to stopped jobs and SIGKILL to those /// Iterates the table, sending SIGTERM to stopped jobs and SIGKILL to those
/// that didn't die from SIGTERM after a while(exit_timeout is 0). /// that didn't die from SIGTERM after a while(exit_timeout is 0).
static void job_stop_timer_cb(uv_timer_t *handle) static void job_stop_timer_cb(uv_timer_t *handle)