📄 callout.c
字号:
/* * Copyright (C) 2001, University of California, Santa Barbara * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Other copyrights might apply to parts of this software and are so * noted when applicable. *//* * Parts of this program has been derived from PIM sparse-mode pimd. * The pimd program is covered by the license in the accompanying file * named "LICENSE.pimd". * * The pimd program is COPYRIGHT 1998 by University of Southern California. * */#include "callout.h"#include "const.h"#include "debug.h"/* the code below implements a callout queue */static int id = 0;/* pointer to the beginning of timeout queue */static struct timeout_q *Q = 0; struct timeout_q { struct timeout_q *next; /* next event */ int id; cfunc_t func; /* function to call */ void *data; /* func's data */ long time; /* time offset to next event*/};void initCallout() { Q = (struct timeout_q *) 0;}void free_all_callouts() { struct timeout_q *p; while (Q) { p = Q; Q = Q->next; free(p); }}/* * perform all the events that should * happen. * elapsed_time: seconds that have passed */void age_callout_queue(long elapsed_time) { struct timeout_q *ptr, *expQ; //trace(TRACE_CALLOUT,"age_callout_queue(%i)",elapsed_time); expQ = Q; ptr = NULL; while (Q) { if (Q->time > elapsed_time) { //trace(TRACE_CALLOUT,"Q->time(%i)",Q->time); Q->time -= elapsed_time; if (ptr) { ptr->next = NULL; break; } return; } else { elapsed_time -= Q->time; //trace(TRACE_CALLOUT,"elapsed time %i)",elapsed_time); ptr = Q; Q = Q->next; } } /* handle queue of expired timers */ while (expQ) { ptr = expQ; if (ptr->func){ //trace(TRACE_CALLOUT,"callout doing something"); ptr->func(ptr->data); } expQ = expQ->next; free(ptr); }}/* * Return in how many seconds age_callout_queue() * would like to be called. * Return NONE (-1) if there are no events pending. */int timer_nextTimer() { //trace(TRACE_CALLOUT_PERIODIC,"callout nextTimer"); if (Q) { if (Q->time < 0) { //trace(TRACE_TIMER, "timer_nextTimer top of queue says %d", // Q->time); return 0; } return Q->time; } return NONE;}/* * sets the timer * int delay; number of units for timeout * cfunc_t action; function to be called on timeout * void *data; what to call the timeout function with * return: id of timer * if there is a problem report ERROR (-1) */int timer_setTimer(long delay, cfunc_t action, void *data) { struct timeout_q *ptr, *node, *prev; //trace(TRACE_CALLOUT|TRACE_TIMER,"setTimer(%i)",delay); /* create a node */ node = (struct timeout_q *)malloc(sizeof(struct timeout_q)); if (node == NULL) { log(LOG_ERR, FALSE, "Malloc Failed in timer_settimer\n"); return ERROR; } 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 { /* traverse queue 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; return node->id; } else { /* keep moving */ delay -= ptr->time; node->time = delay; prev = ptr; ptr = ptr->next; } } prev->next = node; } return node->id;}/* * return: time until the timer is scheduled * if the id doesn't exist it returns DNE (-1) */int timer_leftTimer(int timer_id) { struct timeout_q *ptr; int timeLeft = 0; if (!timer_id){ return DNE; } for (ptr = Q; ptr; ptr = ptr->next) { timeLeft += ptr->time; if (ptr->id == timer_id){ return timeLeft; } } return DNE;}/* clears the associated timer */void timer_clearTimer(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 */ while (ptr) { if (ptr->id == timer_id) { /* got the right node */ /* unlink it from the queue */ if (ptr == Q) { Q = Q->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); return; } prev = ptr; ptr = ptr->next; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -