[cvslog] Module eggdrop1.7: Change committed

cvslog cvs at tsss.org
Sat Oct 13 07:01:02 CST 2001


CVSROOT    : /usr/local/cvsroot
Module     : eggdrop1.7
Commit time: 2001-10-13 12:00:33 UTC
Commited by: stdarg <stdarg at techmonkeys.org>

Modified files:
     src/Makefile.am src/main.c src/net.c src/tclmisc.c
     src/mod/filesys.mod/filesys.c

Added files:
     src/egg_timer.c src/egg_timer.h

Log message:

Added code for C-based microsecond-precision timers.
Made utimer and timer use the new timer stuff. (But utimers and timers don't work with it yet, either does killtimer + killutimer, maybe somebody else can update those :) or I'll do it later)
Added new tcl command, mutimer, to make a timer with a fractional second (i.e. mutimer 500000 hi == run 'hi' after 1/2 second)
Made net.c change the select() timeout based on the shortest timer.
Added a guard clause to lostdcc(n) to make sure n is valid.
When the socket table is reallocated, now the new sockets are marked SOCK_UNUSED (heh).
Fixed a typo in filesys.mod (mine) (looked up the wrong bind table)

---------------------- diff included ----------------------
Index: eggdrop1.7/src/Makefile.am
diff -u eggdrop1.7/src/Makefile.am:1.5 eggdrop1.7/src/Makefile.am:1.6
--- eggdrop1.7/src/Makefile.am:1.5	Fri Oct 12 10:50:25 2001
+++ eggdrop1.7/src/Makefile.am	Sat Oct 13 07:00:22 2001
@@ -1,4 +1,4 @@
-# $Id: Makefile.am,v 1.5 2001/10/12 15:50:25 tothwolf Exp $
+# $Id: Makefile.am,v 1.6 2001/10/13 12:00:22 stdarg Exp $
 
 # FIXME: optionally allow a system wide install by ignoring the line below.
 bindir    = $(exec_prefix)
@@ -33,6 +33,8 @@
 		debug.h \
 		dns.c \
 		dns.h \
+		egg_timer.c \
+		egg_timer.h \
 		eggdrop.h \
 		flags.c \
 		flags.h \
Index: eggdrop1.7/src/egg_timer.c
diff -u /dev/null eggdrop1.7/src/egg_timer.c:1.1
--- /dev/null	Sat Oct 13 07:00:33 2001
+++ eggdrop1.7/src/egg_timer.c	Sat Oct 13 07:00:22 2001
@@ -0,0 +1,159 @@
+#include <stdio.h> /* For NULL */
+#include <sys/time.h> /* For gettimeofday() */
+
+typedef int (*Function)();
+#include "egg_timer.h"
+
+/* Internal use only. */
+typedef struct egg_timer_b {
+	struct egg_timer_b *next;
+	int id;
+	Function callback;
+	void *client_data;
+	egg_timeval_t howlong;
+	egg_timeval_t trigger_time;
+	int flags;
+} egg_timer_t;
+
+/* We keep a sorted list of active timers. */
+static egg_timer_t *timer_list_head = NULL;
+static unsigned int timer_next_id = 1;
+
+/* Based on TclpGetTime from Tcl 8.3.3 */
+int timer_get_time(egg_timeval_t *curtime)
+{
+	struct timeval tv;
+	struct timezone tz;
+
+	(void) gettimeofday(&tv, &tz);
+	curtime->sec = tv.tv_sec;
+	curtime->usec = tv.tv_usec;
+	return(0);
+}
+
+int timer_create_complex(egg_timeval_t *howlong, Function callback, void *client_data, int flags)
+{
+	egg_timer_t *timer, *prev, *next;
+	egg_timeval_t trigger_time;
+
+	timer_get_time(&trigger_time);
+	trigger_time.sec += howlong->sec;
+	trigger_time.usec += howlong->usec;
+
+	/* Find out where this should go in the list. */
+	prev = NULL;
+	for (timer = timer_list_head; timer; timer = timer->next) {
+		if (trigger_time.sec < timer->trigger_time.sec) break;
+		if (trigger_time.sec == timer->trigger_time.sec && trigger_time.usec < timer->trigger_time.usec) break;
+		prev = timer;
+	}
+
+	/* Fill out a new timer. */
+	timer = (egg_timer_t *)malloc(sizeof(*timer));
+	timer->callback = callback;
+	timer->client_data = client_data;
+	timer->flags = flags;
+	memcpy(&timer->howlong, howlong, sizeof(*howlong));
+	memcpy(&timer->trigger_time, &trigger_time, sizeof(trigger_time));
+	timer->id = timer_next_id++;
+
+	/* Insert into timer list. */
+	if (prev) {
+		timer->next = prev->next;
+		prev->next = timer;
+	}
+	else {
+		timer->next = timer_list_head;
+		timer_list_head = timer;
+	}
+
+	if (timer_next_id == 0) timer_next_id++;
+
+	return(timer->id);
+}
+
+/* Destroy a timer, given an id. */
+int timer_destroy(int timer_id)
+{
+	egg_timer_t *prev, *timer;
+
+	prev = NULL;
+	for (timer = timer_list_head; timer; timer = timer->next) {
+		if (timer->id == timer_id) break;
+	}
+
+	if (!timer) return(1); /* Not found! */
+
+	/* Unlink it. */
+	if (prev) prev->next = timer->next;
+	else timer_list_head = timer->next;
+
+	free(timer);
+	return(0);
+}
+
+int timer_get_shortest(egg_timeval_t *howlong)
+{
+	egg_timeval_t curtime;
+	egg_timer_t *timer = timer_list_head;
+
+	/* No timers? Boo. */
+	if (!timer) return(1);
+
+	timer_get_time(&curtime);
+
+	if (timer->trigger_time.sec <= curtime.sec) howlong->sec = 0;
+	else howlong->sec = timer->trigger_time.sec - curtime.sec;
+
+	if (timer->trigger_time.usec <= curtime.usec) howlong->usec = 0;
+	else howlong->usec = timer->trigger_time.usec - curtime.usec;
+
+	return(0);
+}
+
+int timer_run()
+{
+	egg_timeval_t curtime;
+	egg_timer_t *timer;
+	Function callback;
+	void *client_data;
+
+	while (timer = timer_list_head) {
+		timer_get_time(&curtime);
+		if (timer->trigger_time.sec > curtime.sec || (timer->trigger_time.sec == curtime.sec && timer->trigger_time.usec > curtime.usec)) break;
+
+		callback = timer->callback;
+		client_data = timer->client_data;
+
+		if (timer->flags & TIMER_REPEAT) {
+			egg_timer_t *prev, *tptr;
+
+			/* Update timer. */
+			timer->trigger_time.sec += timer->howlong.sec;
+			timer->trigger_time.usec += timer->howlong.usec;
+
+			timer_list_head = timer_list_head->next;
+
+			prev = NULL;
+			for (tptr = timer_list_head; tptr; tptr = tptr->next) {
+				if (tptr->trigger_time.sec > timer->trigger_time.sec || (tptr->trigger_time.sec == timer->trigger_time.sec && tptr->trigger_time.usec > timer->trigger_time.usec)) break;
+				prev = tptr;
+			}
+			if (prev) {
+				timer->next = prev->next;
+				prev->next = timer;
+			}
+			else {
+				timer->next = timer_list_head;
+				timer_list_head = timer;
+			}
+		}
+		else {
+			timer_list_head = timer_list_head->next;
+			free(timer);
+		}
+
+		callback(client_data);
+	}
+	return(0);
+}
Index: eggdrop1.7/src/egg_timer.h
diff -u /dev/null eggdrop1.7/src/egg_timer.h:1.1
--- /dev/null	Sat Oct 13 07:00:33 2001
+++ eggdrop1.7/src/egg_timer.h	Sat Oct 13 07:00:22 2001
@@ -0,0 +1,23 @@
+#ifndef _EGG_TIMER_H_
+#define _EGG_TIMER_H_
+
+typedef struct egg_timeval_b {
+	int sec;
+	int usec;
+} egg_timeval_t;
+
+#define TIMER_REPEAT 1
+
+/* Create a simple timer with no client data and no flags. */
+#define timer_create(howlong,callback) timer_create_complex(howlong, callback, NULL, 0)
+
+/* Create a simple timer with no client data, but it repeats. */
+#define timer_create_repeater(howlong,callback) timer_create_complex(howlong, callback, NULL, TIMER_REPEAT)
+
+int timer_get_time(egg_timeval_t *curtime);
+int timer_create_complex(egg_timeval_t *howlong, Function callback, void *client_data, int flags);
+int timer_destroy(int timer_id);
+int timer_get_shortest(egg_timeval_t *howlong);
+int timer_run();
+
+#endif /* _EGG_TIMER_H_ */
Index: eggdrop1.7/src/main.c
diff -u eggdrop1.7/src/main.c:1.81 eggdrop1.7/src/main.c:1.82
--- eggdrop1.7/src/main.c:1.81	Fri Oct 12 10:50:26 2001
+++ eggdrop1.7/src/main.c	Sat Oct 13 07:00:22 2001
@@ -5,7 +5,7 @@
  *   command line arguments
  *   context and assert debugging
  *
- * $Id: main.c,v 1.81 2001/10/12 15:50:26 tothwolf Exp $
+ * $Id: main.c,v 1.82 2001/10/13 12:00:22 stdarg Exp $
  */
 /*
  * Copyright (C) 1997 Robey Pointer
@@ -53,6 +53,7 @@
 #include "modules.h"
 #include "tandem.h"
 #include "bg.h"
+#include "egg_timer.h"
 
 #include "adns/adns.h"
 
@@ -486,6 +487,7 @@
   static int cnt = 0;
   int miltime;
 
+  call_hook(HOOK_SECONDLY);	/* Will be removed later */
   do_check_timers(&utimer);	/* Secondly timers */
   cnt++;
   if (cnt >= 10) {		/* Every 10 seconds */
@@ -666,6 +668,7 @@
   FILE *f;
   struct sigaction sv;
   struct chanset_t *chan;
+  egg_timeval_t howlong;
 
 #ifdef DEBUG
   /* Make sure it can write core, if you make debug. Else it's pretty
@@ -875,7 +878,9 @@
   add_help_reference("cmds1.help");
   add_help_reference("cmds2.help");
   add_help_reference("core.help");
-  add_hook(HOOK_SECONDLY, (Function) core_secondly);
+  howlong.sec = 1;
+  howlong.usec = 0;
+  timer_create_repeater(&howlong, (Function) core_secondly);
   add_hook(HOOK_MINUTELY, (Function) core_minutely);
   add_hook(HOOK_HOURLY, (Function) core_hourly);
   add_hook(HOOK_REHASH, (Function) event_rehash);
@@ -902,8 +907,9 @@
      */
     now = time(NULL);
     random();			/* Woop, lets really jumble things */
+    timer_run();
     if (now != then) {		/* Once a second */
-      call_hook(HOOK_SECONDLY);
+      /* call_hook(HOOK_SECONDLY); */
       then = now;
     }
 
Index: eggdrop1.7/src/mod/filesys.mod/filesys.c
diff -u eggdrop1.7/src/mod/filesys.mod/filesys.c:1.54 eggdrop1.7/src/mod/filesys.mod/filesys.c:1.55
--- eggdrop1.7/src/mod/filesys.mod/filesys.c:1.54	Thu Oct 11 08:01:35 2001
+++ eggdrop1.7/src/mod/filesys.mod/filesys.c	Sat Oct 13 07:00:22 2001
@@ -2,7 +2,7 @@
  * filesys.c -- part of filesys.mod
  *   main file of the filesys eggdrop module
  *
- * $Id: filesys.c,v 1.54 2001/10/11 13:01:35 tothwolf Exp $
+ * $Id: filesys.c,v 1.55 2001/10/13 12:00:22 stdarg Exp $
  */
 /*
  * Copyright (C) 1997 Robey Pointer
@@ -972,7 +972,7 @@
   add_tcl_strings(mystrings);
   add_tcl_ints(myints);
   H_fil = add_bind_table("fil", 0, builtin_fil);
-  BT_dcc = find_bind_table("dcc");
+  BT_dcc = find_bind_table2("dcc");
   if (BT_dcc) add_builtins2(BT_dcc, mydcc);
   add_builtins(H_fil, myfiles);
   add_builtins(H_load, myload);
Index: eggdrop1.7/src/net.c
diff -u eggdrop1.7/src/net.c:1.45 eggdrop1.7/src/net.c:1.46
--- eggdrop1.7/src/net.c:1.45	Fri Oct 12 10:50:26 2001
+++ eggdrop1.7/src/net.c	Sat Oct 13 07:00:22 2001
@@ -2,7 +2,7 @@
  * net.c -- handles:
  *   all raw network i/o
  * 
- * $Id: net.c,v 1.45 2001/10/12 15:50:26 tothwolf Exp $
+ * $Id: net.c,v 1.46 2001/10/13 12:00:22 stdarg Exp $
  */
 /* 
  * This is hereby released into the public domain.
@@ -27,6 +27,7 @@
 #include <setjmp.h>
 
 #include "adns/adns.h"
+#include "egg_timer.h"
 
 #if !HAVE_GETDTABLESIZE
 #  ifdef FD_SETSIZE
@@ -256,9 +257,12 @@
   }
 
   if (i == MAXSOCKS) {
+    int j;
+
     /* Expand table by 5 */
     socklist = (sock_list *)realloc(socklist, (MAXSOCKS+5) * sizeof(sock_list));
     memset(socklist+MAXSOCKS, 0, 5 * sizeof(sock_list));
+    for (j = 0; j < 5; j++) socklist[MAXSOCKS+j].flags = SOCK_UNUSED;
     MAXSOCKS += 5;
   }
 
@@ -816,15 +820,24 @@
   struct timeval t, tnow;
   struct timeval *pt = &t;
   int grab = 511;
+  egg_timeval_t howlong;
 
   fds = getdtablesize();
 #ifdef FD_SETSIZE
   if (fds > FD_SETSIZE)
     fds = FD_SETSIZE;		/* Fixes YET ANOTHER freebsd bug!!! */
 #endif
-  /* timeout: 1 sec */
-  t.tv_sec = 1;
-  t.tv_usec = 0;
+
+  if (timer_get_shortest(&howlong)) {
+    /* No timer, default to 1 second. */
+    t.tv_sec = 1;
+    t.tv_usec = 0;
+  }
+  else {
+    t.tv_sec = howlong.sec;
+    t.tv_usec = howlong.usec;
+  }
+
   FD_ZERO(&fd);
   
   for (i = 0; i < MAXSOCKS; i++)
Index: eggdrop1.7/src/tclmisc.c
diff -u eggdrop1.7/src/tclmisc.c:1.29 eggdrop1.7/src/tclmisc.c:1.30
--- eggdrop1.7/src/tclmisc.c:1.29	Wed Oct 10 09:50:01 2001
+++ eggdrop1.7/src/tclmisc.c	Sat Oct 13 07:00:22 2001
@@ -3,7 +3,7 @@
  *   Tcl stubs for file system commands
  *   Tcl stubs for everything else
  *
- * $Id: tclmisc.c,v 1.29 2001/10/10 14:50:01 tothwolf Exp $
+ * $Id: tclmisc.c,v 1.30 2001/10/13 12:00:22 stdarg Exp $
  */
 /*
  * Copyright (C) 1997 Robey Pointer
@@ -29,6 +29,7 @@
 #include "modules.h"
 #include "tandem.h"
 #include "md5.h"
+#include "egg_timer.h"
 #ifdef HAVE_UNAME
 #include <sys/utsname.h>
 #endif
@@ -134,6 +135,19 @@
   return TCL_OK;
 }
 
+typedef struct {
+  Tcl_Interp *irp;
+  char *script;
+} tcl_timer_cdata;
+
+static int tcl_timer_callback(tcl_timer_cdata *cdata)
+{
+  Tcl_Eval(cdata->irp, cdata->script);
+  free(cdata->script);
+  free(cdata);
+  return(0);
+}
+
 static int tcl_timer STDVAR
 {
   unsigned long x;
@@ -145,7 +159,15 @@
     return TCL_ERROR;
   }
   if (argv[2][0] != '#') {
-    x = add_timer(&timer, atoi(argv[1]), argv[2], 0L);
+    tcl_timer_cdata *cdata;
+    egg_timeval_t howlong;
+
+    cdata = (tcl_timer_cdata *)malloc(sizeof(*cdata));
+    cdata->irp = irp;
+    malloc_strcpy(cdata->script, argv[2]);
+    howlong.sec = 60 * atoi(argv[1]);
+    howlong.usec = 0;
+    x = timer_create_complex(&howlong, tcl_timer_callback, cdata, 0);
     egg_snprintf(s, sizeof s, "timer%lu", x);
     Tcl_AppendResult(irp, s, NULL);
   }
@@ -163,7 +185,41 @@
     return TCL_ERROR;
   }
   if (argv[2][0] != '#') {
-    x = add_timer(&utimer, atoi(argv[1]), argv[2], 0L);
+    tcl_timer_cdata *cdata;
+    egg_timeval_t howlong;
+
+    cdata = (tcl_timer_cdata *)malloc(sizeof(*cdata));
+    cdata->irp = irp;
+    malloc_strcpy(cdata->script, argv[2]);
+    howlong.sec = atoi(argv[1]);
+    howlong.usec = 0;
+    x = timer_create_complex(&howlong, tcl_timer_callback, cdata, 0);
+    egg_snprintf(s, sizeof s, "timer%lu", x);
+    Tcl_AppendResult(irp, s, NULL);
+  }
+  return TCL_OK;
+}
+
+static int tcl_mutimer STDVAR
+{
+  unsigned long x;
+  char s[16];
+
+  BADARGS(3, 3, " microseconds command");
+  if (atoi(argv[1]) < 0) {
+    Tcl_AppendResult(irp, "time value must be positive", NULL);
+    return TCL_ERROR;
+  }
+  if (argv[2][0] != '#') {
+    tcl_timer_cdata *cdata;
+    egg_timeval_t howlong;
+
+    cdata = (tcl_timer_cdata *)malloc(sizeof(*cdata));
+    cdata->irp = irp;
+    malloc_strcpy(cdata->script, argv[2]);
+    howlong.sec = atoi(argv[1]) / 1000000;
+    howlong.usec = atoi(argv[1]) % 1000000;
+    x = timer_create_complex(&howlong, tcl_timer_callback, cdata, 0);
     egg_snprintf(s, sizeof s, "timer%lu", x);
     Tcl_AppendResult(irp, s, NULL);
   }
@@ -559,6 +615,7 @@
   {"putloglev",		tcl_putloglev},
   {"timer",		tcl_timer},
   {"utimer",		tcl_utimer},
+  {"mutimer",		tcl_mutimer},
   {"killtimer",		tcl_killtimer},
   {"killutimer",	tcl_killutimer},
   {"timers",		tcl_timers},
----------------------- End of diff -----------------------



More information about the Changes mailing list