Skip to content

Commit

Permalink
core/timer: Always use inactive_exit_timestamp if it is set
Browse files Browse the repository at this point in the history
If we're doing a daemon-reload, we'll be going from TIMER_DEAD => TIMER_WAITING,
so we won't use inactive_exit_timestamp because TIMER_DEAD != UNIT_ACTIVE, even
though inactive_exit_timestamp is serialized/deserialized and will be valid after
the daemon-reload.

This issue can lead to timers never firing as we'll always calculate the next
elapse based on the current realtime on daemon-reload, so if daemon-reload happens
often enough, the elapse interval will be moved into the future every time, which
means the timer will never trigger.

To fix the issue, let's always use inactive_exit_timestamp if it is set, and only
fall back to the current realtime if it is not set.

(cherry picked from commit 6546045)
  • Loading branch information
DaanDeMeyer authored and keszybz committed May 31, 2023
1 parent 242ee3f commit d4f1f61
Showing 1 changed file with 4 additions and 6 deletions.
10 changes: 4 additions & 6 deletions src/core/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,12 +401,10 @@ static void timer_enter_waiting(Timer *t, bool time_change) {

if (t->last_trigger.realtime > 0)
b = t->last_trigger.realtime;
else {
if (state_translation_table[t->state] == UNIT_ACTIVE)
b = UNIT(t)->inactive_exit_timestamp.realtime;
else
b = ts.realtime;
}
else if (dual_timestamp_is_set(&UNIT(t)->inactive_exit_timestamp))
b = UNIT(t)->inactive_exit_timestamp.realtime;
else
b = ts.realtime;

r = calendar_spec_next_usec(v->calendar_spec, b, &v->next_elapse);
if (r < 0)
Expand Down

0 comments on commit d4f1f61

Please sign in to comment.