From: Zbigniew Jędrzejewski-Szmek Date: Mon, 27 Jan 2014 05:57:34 +0000 (-0500) Subject: core: add function to tell when job will time out X-Git-Tag: v209~333 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=68db7a3bd9b2f8640c7297382b6d20eb995f7e1e core: add function to tell when job will time out Things will continue when either the job timeout or the unit timeout is reached. Add functionality to access that info. --- diff --git a/src/core/job.c b/src/core/job.c index 7faa8da0e..e6529b61e 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -1086,6 +1086,37 @@ void job_shutdown_magic(Job *j) { asynchronous_sync(); } +int job_get_timeout(Job *j, uint64_t *timeout) { + Unit *u = j->unit; + uint64_t x = -1, y = -1; + int r = 0, q = 0; + + assert(u); + + if (j->timer_event_source) { + r = sd_event_source_get_time(j->timer_event_source, &x); + if (r < 0) + return r; + r = 1; + } + + if (UNIT_VTABLE(u)->get_timeout) { + q = UNIT_VTABLE(u)->get_timeout(u, &y); + if (q < 0) + return q; + } + + if (r == 0 && q == 0) + return 0; + + *timeout = MIN(x, y); + + log_info("job_get_timeout %s %d/%"PRIu64" %d/%"PRIu64" -> 1/%"PRIu64, + j->unit->id, r, x, q, y, *timeout); + + return 1; +} + static const char* const job_state_table[_JOB_STATE_MAX] = { [JOB_WAITING] = "waiting", [JOB_RUNNING] = "running" diff --git a/src/core/job.h b/src/core/job.h index 0500e1208..8cc3a0219 100644 --- a/src/core/job.h +++ b/src/core/job.h @@ -222,3 +222,5 @@ JobMode job_mode_from_string(const char *s) _pure_; const char* job_result_to_string(JobResult t) _const_; JobResult job_result_from_string(const char *s) _pure_; + +int job_get_timeout(Job *j, uint64_t *timeout) _pure_; diff --git a/src/core/mount.c b/src/core/mount.c index bce50548b..90da88382 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -1583,6 +1583,20 @@ static void mount_shutdown(Manager *m) { } } +static int mount_get_timeout(Unit *u, uint64_t *timeout) { + Mount *m = MOUNT(u); + int r; + + if (!m->timer_event_source) + return 0; + + r = sd_event_source_get_time(m->timer_event_source, timeout); + if (r < 0) + return r; + + return 1; +} + static int mount_enumerate(Manager *m) { int r; assert(m); @@ -1796,6 +1810,8 @@ const UnitVTable mount_vtable = { .bus_set_property = bus_mount_set_property, .bus_commit_properties = bus_mount_commit_properties, + .get_timeout = mount_get_timeout, + .enumerate = mount_enumerate, .shutdown = mount_shutdown, diff --git a/src/core/scope.c b/src/core/scope.c index 56c374660..87983f6b1 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -318,6 +318,20 @@ static int scope_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) { return unit_kill_common(u, who, signo, -1, -1, error); } +static int scope_get_timeout(Unit *u, uint64_t *timeout) { + Scope *s = SCOPE(u); + int r; + + if (!s->timer_event_source) + return 0; + + r = sd_event_source_get_time(s->timer_event_source, timeout); + if (r < 0) + return r; + + return 1; +} + static int scope_serialize(Unit *u, FILE *f, FDSet *fds) { Scope *s = SCOPE(u); @@ -478,6 +492,8 @@ const UnitVTable scope_vtable = { .kill = scope_kill, + .get_timeout = scope_get_timeout, + .serialize = scope_serialize, .deserialize_item = scope_deserialize_item, diff --git a/src/core/service.c b/src/core/service.c index a2f0e3577..d949f7a36 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -3401,6 +3401,20 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) { unit_add_to_dbus_queue(u); } +static int service_get_timeout(Unit *u, uint64_t *timeout) { + Service *s = SERVICE(u); + int r; + + if (!s->timer_event_source) + return 0; + + r = sd_event_source_get_time(s->timer_event_source, timeout); + if (r < 0) + return r; + + return 1; +} + #ifdef HAVE_SYSV_COMPAT static int service_enumerate(Manager *m) { @@ -3832,6 +3846,8 @@ const UnitVTable service_vtable = { .bus_set_property = bus_service_set_property, .bus_commit_properties = bus_service_commit_properties, + .get_timeout = service_get_timeout, + #ifdef HAVE_SYSV_COMPAT .enumerate = service_enumerate, #endif diff --git a/src/core/socket.c b/src/core/socket.c index 1f2a2c0aa..7eac0eb66 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -2344,6 +2344,20 @@ static int socket_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) { return unit_kill_common(u, who, signo, -1, SOCKET(u)->control_pid, error); } +static int socket_get_timeout(Unit *u, uint64_t *timeout) { + Socket *s = SOCKET(u); + int r; + + if (!s->timer_event_source) + return 0; + + r = sd_event_source_get_time(s->timer_event_source, timeout); + if (r < 0) + return r; + + return 1; +} + static const char* const socket_state_table[_SOCKET_STATE_MAX] = { [SOCKET_DEAD] = "dead", [SOCKET_START_PRE] = "start-pre", @@ -2408,6 +2422,8 @@ const UnitVTable socket_vtable = { .kill = socket_kill, + .get_timeout = socket_get_timeout, + .serialize = socket_serialize, .deserialize_item = socket_deserialize_item, .distribute_fds = socket_distribute_fds, diff --git a/src/core/swap.c b/src/core/swap.c index 6b204df58..26141e6a3 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -1367,6 +1367,20 @@ static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) { return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error); } +static int swap_get_timeout(Unit *u, uint64_t *timeout) { + Swap *s = SWAP(u); + int r; + + if (!s->timer_event_source) + return 0; + + r = sd_event_source_get_time(s->timer_event_source, timeout); + if (r < 0) + return r; + + return 1; +} + static const char* const swap_state_table[_SWAP_STATE_MAX] = { [SWAP_DEAD] = "dead", [SWAP_ACTIVATING] = "activating", @@ -1429,6 +1443,8 @@ const UnitVTable swap_vtable = { .kill = swap_kill, + .get_timeout = swap_get_timeout, + .serialize = swap_serialize, .deserialize_item = swap_deserialize_item, diff --git a/src/core/unit.h b/src/core/unit.h index 45816eae3..c686aecce 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -410,6 +410,8 @@ struct UnitVTable { /* Called whenever CLOCK_REALTIME made a jump */ void (*time_change)(Unit *u); + int (*get_timeout)(Unit *u, uint64_t *timeout); + /* This is called for each unit type and should be used to * enumerate existing devices and load them. However, * everything that is loaded here should still stay in