/* Callback from the alarm timeout */ static gboolean alarm_ready_cb (gpointer data) { time_t now; if (!alarms) { g_warning ("Alarm triggered, but no alarm present\n"); return FALSE; } timeout_id = 0; now = time (NULL); g_message ("Alarm callback!"); while (alarms) { AlarmRecord *notify_id, *ar; AlarmRecord ar_copy; ar = alarms->data; if (ar->trigger > now) break; g_message ("Process alarm with trigger %lu", ar->trigger); notify_id = ar; ar_copy = *ar; ar = &ar_copy; pop_alarm (); /* This will free the original AlarmRecord; that's why we copy it */ (* ar->alarm_fn) (notify_id, ar->trigger, ar->data); if (ar->destroy_notify_fn) (* ar->destroy_notify_fn) (notify_id, ar->data); } /* We need this check because one of the alarm_fn above may have * re-entered and added an alarm of its own, so the timer will * already be set up. */ if (alarms) setup_timeout (); return FALSE; }
static void timer_intr(void) { static struct Message m; current_pcb->time_elapsed ++; if (current_pcb->time_elapsed % NR_PROC_TIME == 0) { need_sched = TRUE; } if (alarm_queue != NULL) { alarm_queue->remain_time --; while (alarm_queue != NULL && alarm_queue->remain_time <= 0) { m.type = TIMER_ALRM_FIRE; send(alarm_queue->pid, &m); pop_alarm(); } } }
/** * alarm_remove: * @alarm: A queued alarm identifier. * * Removes an alarm from the alarm queue. **/ void alarm_remove (gpointer alarm) { AlarmRecord *notify_id, *ar; AlarmRecord ar_copy; AlarmRecord *old_head; GList *l; g_return_if_fail (alarm != NULL); ar = alarm; l = g_list_find (alarms, ar); if (!l) { g_message (G_STRLOC ": Requested removal of nonexistent alarm!"); return; } old_head = alarms->data; notify_id = ar; if (old_head == ar) { ar_copy = *ar; ar = &ar_copy; pop_alarm (); /* This will free the original AlarmRecord; that's why we copy it */ } else { alarms = g_list_delete_link (alarms, l); } /* Reset the timeout */ if (!alarms) { g_source_remove (timeout_id); timeout_id = 0; } /* Notify about destructiono of the alarm */ if (ar->destroy_notify_fn) (* ar->destroy_notify_fn) (notify_id, ar->data); }