diff options
Diffstat (limited to 'src/core/job.c')
-rw-r--r-- | src/core/job.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/src/core/job.c b/src/core/job.c index a02f1bb2bc..5067006d63 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -576,6 +576,7 @@ int job_run_and_invalidate(Job *j) { if (!job_is_runnable(j)) return -EAGAIN; + job_start_timer(j, true); job_set_state(j, JOB_RUNNING); job_add_to_dbus_queue(j); @@ -949,22 +950,45 @@ static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *user return 0; } -int job_start_timer(Job *j) { +int job_start_timer(Job *j, bool job_running) { int r; + usec_t run_begin, timeout_time, old_timeout_time; - if (j->timer_event_source) - return 0; + if (job_running) { + if (j->unit->job_running_timeout == USEC_INFINITY) + return 0; - j->begin_usec = now(CLOCK_MONOTONIC); + run_begin = now(CLOCK_MONOTONIC); + timeout_time = usec_add(run_begin, j->unit->job_running_timeout); - if (j->unit->job_timeout == USEC_INFINITY) - return 0; + if (j->timer_event_source) { + /* Update only if JobRunningTimeoutSec= results in earlier timeout */ + r = sd_event_source_get_time(j->timer_event_source, &old_timeout_time); + if (r < 0) + return r; + + if (old_timeout_time <= timeout_time) + return 0; + + return sd_event_source_set_time(j->timer_event_source, timeout_time); + } + } else { + if (j->timer_event_source) + return 0; + + j->begin_usec = now(CLOCK_MONOTONIC); + + if (j->unit->job_timeout == USEC_INFINITY) + return 0; + + timeout_time = usec_add(j->begin_usec, j->unit->job_timeout); + } r = sd_event_add_time( j->manager->event, &j->timer_event_source, CLOCK_MONOTONIC, - usec_add(j->begin_usec, j->unit->job_timeout), 0, + timeout_time, 0, job_dispatch_timer, j); if (r < 0) return r; |