OSDN Git Service

Add option for schedule_next_instance to force rescheduling
authorZach Johnson <zachoverflow@google.com>
Thu, 26 Mar 2015 22:07:43 +0000 (15:07 -0700)
committerAndre Eisenbach <eisenbach@google.com>
Thu, 26 Mar 2015 22:42:04 +0000 (22:42 +0000)
If we're rescheduling a periodic timer in the context of an alarm
expiration we want to force rescheduling to happen.

The alarm at the front of the list after scheduling the next
instance may be a different alarm. The old code would assume it was
already scheduled correctly, meaning nothing would ever get scheduled
after that.

Change-Id: I8accf5d004e69dfd6477ab7ec529eea42b3a88f8

osi/src/alarm.c

index 9a70472..42c3da1 100644 (file)
@@ -72,7 +72,7 @@ static semaphore_t *alarm_expired;
 static bool lazy_initialize(void);
 static period_ms_t now(void);
 static void alarm_set_internal(alarm_t *alarm, period_ms_t deadline, alarm_callback_t cb, void *data, bool is_periodic);
-static void schedule_next_instance(alarm_t *alarm);
+static void schedule_next_instance(alarm_t *alarm, bool force_reschedule);
 static void reschedule_root_alarm(void);
 static void timer_callback(void *data);
 static void callback_dispatch(void *context);
@@ -145,7 +145,7 @@ static void alarm_set_internal(alarm_t *alarm, period_ms_t period, alarm_callbac
   alarm->callback = cb;
   alarm->data = data;
 
-  schedule_next_instance(alarm);
+  schedule_next_instance(alarm, false);
 
   pthread_mutex_unlock(&monitor);
 }
@@ -222,7 +222,7 @@ static period_ms_t now(void) {
 }
 
 // Must be called with monitor held
-static void schedule_next_instance(alarm_t *alarm) {
+static void schedule_next_instance(alarm_t *alarm, bool force_reschedule) {
   // If the alarm is currently set and it's at the start of the list,
   // we'll need to re-schedule since we've adjusted the earliest deadline.
   bool needs_reschedule = (!list_is_empty(alarms) && list_front(alarms) == alarm);
@@ -247,7 +247,7 @@ static void schedule_next_instance(alarm_t *alarm) {
     }
 
   // If the new alarm has the earliest deadline, we need to re-evaluate our schedule.
-  if (needs_reschedule || (!list_is_empty(alarms) && list_front(alarms) == alarm))
+  if (force_reschedule || needs_reschedule || (!list_is_empty(alarms) && list_front(alarms) == alarm))
     reschedule_root_alarm();
 }
 
@@ -338,7 +338,7 @@ static void callback_dispatch(UNUSED_ATTR void *context) {
     void *data = alarm->data;
 
     if (alarm->is_periodic) {
-      schedule_next_instance(alarm);
+      schedule_next_instance(alarm, true);
     } else {
       reschedule_root_alarm();