/* * Create a timer * @delay: Number of seconds for timeout * @action: Timer callback * @data: Optional callback data, must be a dynically allocated ptr */ int timer_set(int delay, cfunc_t action, void *data) { struct timeout_q *ptr, *node, *prev; #ifdef CALLOUT_DEBUG IF_DEBUG(DEBUG_TIMEOUT) logit(LOG_DEBUG, 0, "setting timer:"); print_Q(); #endif /* create a node */ node = calloc(1, sizeof(struct timeout_q)); if (!node) { logit(LOG_ERR, 0, "Ran out of memory in %s()", __func__); return -1; } node->func = action; node->data = data; node->time = delay; node->next = 0; node->id = next_id(); prev = ptr = Q; /* insert node in the queue */ /* if the queue is empty, insert the node and return */ if (!Q) Q = node; else { /* chase the pointer looking for the right place */ while (ptr) { if (delay < ptr->time) { /* right place */ node->next = ptr; if (ptr == Q) Q = node; else prev->next = node; ptr->time -= node->time; print_Q(); return node->id; } /* keep moving */ delay -= ptr->time; node->time = delay; prev = ptr; ptr = ptr->next; } prev->next = node; } print_Q(); return node->id; }
/* * elapsed_time seconds have passed; perform all the events that should * happen. */ void timer_age_queue(int elapsed_time) { struct timeout_q *ptr; #ifdef CALLOUT_DEBUG IF_DEBUG(DEBUG_TIMEOUT) logit(LOG_DEBUG, 0, "aging queue (elapsed time %d):", elapsed_time); print_Q(); #endif for (ptr = Q; Q; ptr = Q) { if (ptr->time > elapsed_time) { ptr->time -= elapsed_time; break; } /* ptr has expired, push Q */ Q = ptr->next; elapsed_time -= ptr->time; if (ptr->func) ptr->func(ptr->data); free(ptr); } }
/* * sets the timer * @delay: number of units for timeout * @action: function to be called on timeout * @data: what to call the timeout function with */ int timer_setTimer(int delay, cfunc_t action, void *data) { struct timeout_q *ptr, *node, *prev; int i = 0; /* create a node */ node = (struct timeout_q *)malloc(sizeof(struct timeout_q)); if (!node) { logit(LOG_WARNING, 0, "Malloc failed in timer_setTimer()\n"); return -1; } node->func = action; node->data = data; node->time = delay; node->next = 0; node->id = ++id; prev = ptr = Q; /* insert node in the queue */ /* if the queue is empty, insert the node and return */ if (!Q) Q = node; else { /* chase the pointer looking for the right place */ while (ptr) { if (delay < ptr->time) { /* right place */ node->next = ptr; if (ptr == Q) Q = node; else prev->next = node; ptr->time -= node->time; print_Q(); IF_DEBUG(DEBUG_TIMEOUT) { logit(LOG_DEBUG, 0, "created timeout %d (#%d)", node->id, i); } return node->id; } else { /* keep moving */ delay -= ptr->time; node->time = delay; prev = ptr; ptr = ptr->next; } i++; }
/* clears the associated timer */ void timer_clear(int timer_id) { struct timeout_q *ptr, *prev; if (!timer_id) return; prev = ptr = Q; /* * find the right node, delete it. the subsequent node's time * gets bumped up */ print_Q(); while (ptr) { if (ptr->id != timer_id) { prev = ptr; ptr = ptr->next; continue; } /* Found it, now unlink it from the queue */ if (ptr == Q) Q = ptr->next; else prev->next = ptr->next; /* increment next node if any */ if (ptr->next != 0) (ptr->next)->time += ptr->time; if (ptr->data) free(ptr->data); free(ptr); break; } print_Q(); }