int timers_process() { struct timeval now; core_get_clock(&now); pom_mutex_lock(&timer_main_lock); struct timer_queue *tq; tq = timer_queues; while (tq) { while (tq->head && timercmp(&tq->head->expires, &now, <)) { // Dequeue the timer struct timer *tmp = tq->head; tq->head = tq->head->next; if (tq->head) tq->head->prev = NULL; else tq->tail = NULL; tmp->next = NULL; tmp->prev = NULL; tmp->queue = NULL; pom_mutex_unlock(&timer_main_lock); // Process it debug_timer( "Timer 0x%lx reached. Starting handler ...", (unsigned long) tmp); if ((*tmp->handler) (tmp->priv, &now) != POM_OK) { return POM_ERR; } pom_mutex_lock(&timer_main_lock); } tq = tq->next; } pom_mutex_unlock(&timer_main_lock); return POM_OK; }
int timers_process() { static int processing = 0; int res = pthread_mutex_trylock(&timer_main_lock); if (res == EBUSY) { // Already locked, give up return POM_OK; } else if (res) { // Something went wrong pomlog(POMLOG_ERR "Error while trying to lock the main timer lock : %s", pom_strerror(res)); abort(); return POM_ERR; } // Another thread is already processing the timers, drop out if (processing) { pom_mutex_unlock(&timer_main_lock); return POM_OK; } processing = 1; ptime now = core_get_clock(); struct timer_queue *tq; tq = timer_queues; while (tq) { while (tq->head && (tq->head->expires < now)) { // Dequeue the timer struct timer *tmp = tq->head; tq->head = tq->head->next; if (tq->head) tq->head->prev = NULL; else tq->tail = NULL; tmp->next = NULL; tmp->prev = NULL; tmp->queue = NULL; pom_mutex_unlock(&timer_main_lock); registry_perf_dec(perf_timer_queued, 1); // Process it debug_timer( "Timer 0x%lx reached. Starting handler ...", (unsigned long) tmp); if ((*tmp->handler) (tmp->priv, now) != POM_OK) { return POM_ERR; } registry_perf_inc(perf_timer_processed, 1); pom_mutex_lock(&timer_main_lock); } tq = tq->next; } processing = 0; pom_mutex_unlock(&timer_main_lock); return POM_OK; }
int timer_queue(struct timer *t, unsigned int expiry) { pom_mutex_lock(&timer_main_lock); // Timer is still queued, dequeue it if (t->queue) { if (t->prev) { t->prev->next = t->next; } else { t->queue->head = t->next; if (t->queue->head) t->queue->head->prev = NULL; } if (t->next) { t->next->prev = t->prev; } else { t->queue->tail = t->prev; if (t->queue->tail) t->queue->tail->next = NULL; } t->queue = NULL; t->prev = NULL; t->next = NULL; } struct timer_queue *tq = timer_queues; // First find the right queue or create it if (!tq) { // There is no queue yet tq = malloc(sizeof(struct timer_queue)); if (!tq) { pom_mutex_unlock(&timer_main_lock); pom_oom(sizeof(struct timer_queue)); return POM_ERR; } memset(tq, 0, sizeof(struct timer_queue)); timer_queues = tq; tq->expiry = expiry; } else { while (tq) { if (tq->expiry == expiry) { // The right queue already exists break; } else if (tq->expiry > expiry) { // The right queue doesn't exists and we are too far in the list struct timer_queue *tmp; tmp = malloc(sizeof(struct timer_queue)); if (!tmp) { pom_oom(sizeof(struct timer_queue)); pom_mutex_unlock(&timer_main_lock); return POM_ERR; } memset(tmp, 0, sizeof(struct timer_queue)); tmp->prev = tq->prev; tmp->next = tq; tq->prev = tmp; if (tmp->prev) tmp->prev->next = tmp; else timer_queues = tmp; tq = tmp; tq->expiry = expiry; break; } else if (!tq->next) { // Looks like we are at the end of our list struct timer_queue *tmp; tmp = malloc(sizeof(struct timer_queue)); if (!tmp) { pom_oom(sizeof(struct timer_queue)); pom_mutex_unlock(&timer_main_lock); return POM_ERR; } memset(tmp, 0, sizeof(struct timer_queue)); tmp->prev = tq; tq->next = tmp; tq = tmp; tq->expiry = expiry; break; } tq = tq->next; } } // Now we can queue the timer if (tq->head == NULL) { tq->head = t; tq->tail = t; } else { t->prev = tq->tail; tq->tail = t; t->prev->next = t; } // Update the expiry time core_get_clock(&t->expires); t->expires.tv_sec += expiry; t->queue = tq; pom_mutex_unlock(&timer_main_lock); return POM_OK; }