event.c
上传用户:liugui
上传日期:2007-01-04
资源大小:822k
文件大小:5k
- /*
- * $Id: event.c,v 1.24 1998/12/02 05:03:28 wessels Exp $
- *
- * DEBUG: section 41 Event Processing
- * AUTHOR: Henrik Nordstrom
- *
- * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
- * ----------------------------------------------------------
- *
- * Squid is the result of efforts by numerous individuals from the
- * Internet community. Development is led by Duane Wessels of the
- * National Laboratory for Applied Network Research and funded by the
- * National Science Foundation. Squid is Copyrighted (C) 1998 by
- * Duane Wessels and the University of California San Diego. Please
- * see the COPYRIGHT file for full details. Squid incorporates
- * software developed and/or copyrighted by other sources. Please see
- * the CREDITS file for full details.
- *
- * 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, USA.
- *
- */
- #include "squid.h"
- /* The list of event processes */
- struct ev_entry {
- EVH *func;
- void *arg;
- const char *name;
- double when;
- struct ev_entry *next;
- int weight;
- int id;
- };
- static struct ev_entry *tasks = NULL;
- static OBJH eventDump;
- static int run_id = 0;
- void
- eventAdd(const char *name, EVH * func, void *arg, double when, int weight)
- {
- struct ev_entry *event = xcalloc(1, sizeof(struct ev_entry));
- struct ev_entry **E;
- event->func = func;
- event->arg = arg;
- event->name = name;
- event->when = current_dtime + when;
- event->weight = weight;
- event->id = run_id;
- if (NULL != arg)
- cbdataLock(arg);
- debug(41, 7) ("eventAdd: Adding '%s', in %f secondsn", name, when);
- /* Insert after the last event with the same or earlier time */
- for (E = &tasks; *E; E = &(*E)->next) {
- if ((*E)->when > event->when)
- break;
- }
- event->next = *E;
- *E = event;
- }
- /* same as eventAdd but adds a random offset within +-1/3 of delta_ish */
- void
- eventAddIsh(const char *name, EVH * func, void *arg, double delta_ish, int weight)
- {
- if (delta_ish >= 3.0) {
- const double two_third = (2.0 * delta_ish) / 3.0;
- delta_ish = two_third + (drand48() * two_third);
- /*
- * I'm sure drand48() isn't portable. Tell me what function
- * you have that returns a random double value in the range 0,1.
- */
- }
- eventAdd(name, func, arg, delta_ish, weight);
- }
- void
- eventDelete(EVH * func, void *arg)
- {
- struct ev_entry **E;
- struct ev_entry *event;
- for (E = &tasks; (event = *E) != NULL; E = &(*E)->next) {
- if (event->func != func)
- continue;
- if (event->arg != arg)
- continue;
- *E = event->next;
- if (NULL != event->arg)
- cbdataUnlock(event->arg);
- xfree(event);
- return;
- }
- debug_trap("eventDelete: event not found");
- }
- void
- eventRun(void)
- {
- struct ev_entry *event = NULL;
- EVH *func;
- void *arg;
- int weight = 0;
- if (NULL == tasks)
- return;
- if (tasks->when > current_dtime)
- return;
- run_id++;
- debug(41, 5) ("eventRun: RUN ID %dn", run_id);
- while ((event = tasks)) {
- if (event->when > current_dtime)
- break;
- if (event->id == run_id) /* was added during this run */
- break;
- if (weight)
- break;
- func = event->func;
- arg = event->arg;
- event->func = NULL;
- event->arg = NULL;
- tasks = event->next;
- if (NULL != arg) {
- int valid = cbdataValid(arg);
- cbdataUnlock(arg);
- if (!valid)
- return;
- }
- weight += event->weight;
- debug(41, 5) ("eventRun: Running '%s', id %dn", event->name, event->id);
- func(arg);
- safe_free(event);
- }
- }
- time_t
- eventNextTime(void)
- {
- if (!tasks)
- return (time_t) 10;
- return (time_t) ((tasks->when - current_dtime) * 1000);
- }
- void
- eventInit(void)
- {
- cachemgrRegister("events",
- "Event Queue",
- eventDump, 0, 1);
- }
- static void
- eventDump(StoreEntry * sentry)
- {
- struct ev_entry *e = tasks;
- storeAppendPrintf(sentry, "%st%sn",
- "Operation",
- "Next Execution");
- while (e != NULL) {
- storeAppendPrintf(sentry, "%st%f secondsn",
- e->name, e->when - current_dtime);
- e = e->next;
- }
- }
- void
- eventFreeMemory(void)
- {
- struct ev_entry *event;
- while ((event = tasks)) {
- if (NULL != event->arg)
- cbdataUnlock(event->arg);
- xfree(event);
- }
- tasks = NULL;
- }
- int
- eventFind(EVH * func, void *arg)
- {
- struct ev_entry *event;
- for (event = tasks; event != NULL; event = event->next) {
- if (event->func == func && event->arg == arg)
- return 1;
- }
- return 0;
- }