summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-04-23 17:42:31 -0300
committerLennart Poettering <lennart@poettering.net>2013-04-23 17:42:31 -0300
commite41e194340f9a8dbd982b5030449281c3c8bf0dd (patch)
tree4360b87805b18a84178d98d32a70f61cd0128082
parent0e99f1d6f8d41677d401a89f97a887a92fc7084a (diff)
timer: make sure we restart timers even if units are still running or if one of their conditions fails
-rw-r--r--TODO6
-rw-r--r--src/core/timer.c30
-rw-r--r--src/core/timer.h2
3 files changed, 20 insertions, 18 deletions
diff --git a/TODO b/TODO
index de950d7a88..fe27d2b2a0 100644
--- a/TODO
+++ b/TODO
@@ -24,12 +24,6 @@ Fedora 19:
* localed:
- localectl: support new converted x11→console keymaps
-* timer logic is confused by units which are skipped due to failing condition
- http://lists.freedesktop.org/archives/systemd-devel/2013-February/008816.html
-
-* timer logic is also confused if a service it triggers hasn't finished when the next timer elapses:
- http://lists.freedesktop.org/archives/systemd-devel/2013-February/009021.html
-
Features:
* see if we can fix https://bugs.freedesktop.org/show_bug.cgi?id=63672
diff --git a/src/core/timer.c b/src/core/timer.c
index b5d895f048..b8039d82ec 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -251,11 +251,6 @@ static void timer_enter_waiting(Timer *t, bool initial) {
if (r < 0)
continue;
- if (!initial && v->next_elapse < ts.realtime) {
- v->disabled = true;
- continue;
- }
-
if (!found_realtime)
t->next_elapse_realtime = v->next_elapse;
else
@@ -284,18 +279,26 @@ static void timer_enter_waiting(Timer *t, bool initial) {
case TIMER_UNIT_ACTIVE:
- if (UNIT_TRIGGER(UNIT(t))->inactive_exit_timestamp.monotonic <= 0)
+ base = UNIT_TRIGGER(UNIT(t))->inactive_exit_timestamp.monotonic;
+
+ if (base <= 0)
+ base = t->last_trigger_monotonic;
+
+ if (base <= 0)
continue;
- base = UNIT_TRIGGER(UNIT(t))->inactive_exit_timestamp.monotonic;
break;
case TIMER_UNIT_INACTIVE:
- if (UNIT_TRIGGER(UNIT(t))->inactive_enter_timestamp.monotonic <= 0)
+ base = UNIT_TRIGGER(UNIT(t))->inactive_enter_timestamp.monotonic;
+
+ if (base <= 0)
+ base = t->last_trigger_monotonic;
+
+ if (base <= 0)
continue;
- base = UNIT_TRIGGER(UNIT(t))->inactive_enter_timestamp.monotonic;
break;
default:
@@ -304,7 +307,10 @@ static void timer_enter_waiting(Timer *t, bool initial) {
v->next_elapse = base + v->value;
- if (!initial && v->next_elapse < ts.monotonic) {
+ if (!initial &&
+ v->next_elapse < ts.monotonic &&
+ (v->base == TIMER_ACTIVE || v->base == TIMER_BOOT || v->base == TIMER_STARTUP)) {
+ /* This is a one time trigger, disable it now */
v->disabled = true;
continue;
}
@@ -376,6 +382,8 @@ static void timer_enter_running(Timer *t) {
if (r < 0)
goto fail;
+ t->last_trigger_monotonic = now(CLOCK_MONOTONIC);
+
timer_set_state(t, TIMER_RUNNING);
return;
@@ -488,8 +496,6 @@ static void timer_trigger_notify(Unit *u, Unit *other) {
assert(u);
assert(other);
- log_error("NOTIFY!");
-
if (other->load_state != UNIT_LOADED)
return;
diff --git a/src/core/timer.h b/src/core/timer.h
index 163bd6c3be..fed15e9165 100644
--- a/src/core/timer.h
+++ b/src/core/timer.h
@@ -79,6 +79,8 @@ struct Timer {
Watch realtime_watch;
TimerResult result;
+
+ usec_t last_trigger_monotonic;
};
void timer_free_values(Timer *t);