]> jfr.im git - irc/quakenet/newserv.git/blobdiff - core/schedule.c
CHANSERV: remove accidental sendemail from SETEMAIL command.
[irc/quakenet/newserv.git] / core / schedule.c
index dbd3c427988957a1b769f134a0bbea3e1972a97f..7202155e630d8c6ca5da184f29590e1f88e91aa6 100644 (file)
@@ -27,7 +27,6 @@ int schedexes;
 void schedulestats(int hooknum, void *arg);
 
 void initschedule() {
-  initschedulealloc();
   events=NULL;
   schedadds=scheddels=schedexes=scheddelfast=0;
   registerhook(HOOK_CORE_STATSREQUEST, &schedulestats);
@@ -36,6 +35,11 @@ void initschedule() {
   events=(schedule **)malloc(INITSCHEDSIZE*sizeof(schedule *));
 }
 
+void finischedule() {
+  deregisterhook(HOOK_CORE_STATSREQUEST, &schedulestats);
+  free(events);
+}
+
 void schedule_heapify(int index) {
   int firstindex=index;
   schedule *ep;
@@ -162,11 +166,12 @@ void *scheduleoneshot(time_t when, ScheduleCallback callback, void *arg) {
   sp->repeatcount=1;
   sp->callback=callback;
   sp->callbackparam=arg;
+  sp->deleted=0;
 
   insertschedule(sp);
   
 #ifdef SCHEDDEBUG
-  Error("schedule",ERR_DEBUG,"scheduleoneshot: (%ld, %x, %x) = %x",when, callback, arg, sp);
+  Error("schedule",ERR_DEBUG,"scheduleoneshot: (%ld, %x, %x) = %x",when, (unsigned int)callback, (unsigned int)arg, (unsigned int)sp);
 #endif
 
   return (void *)sp;
@@ -187,6 +192,7 @@ void *schedulerecurring(time_t first, int count, time_t interval, ScheduleCallba
   sp->repeatcount=(count-1);
   sp->callback=callback;
   sp->callbackparam=arg;
+  sp->deleted=0;
   
   insertschedule(sp);
   
@@ -201,19 +207,23 @@ void deleteschedule(void *sch, ScheduleCallback callback, void *arg) {
    * pass it in here for an O(1) *cough* O(lg n) delete */
 
 #ifdef SCHEDDEBUG
-  Error("schedule",ERR_DEBUG,"deleteschedule(%x,%x,%x)",sch,callback, arg);
+  Error("schedule",ERR_DEBUG,"deleteschedule(%x,%x,%x)",(unsigned int)sch,(unsigned int)callback, (unsigned int)arg);
 #endif
 
   if (sch) {
     sp=(schedule *)sch;
     /* Double check the params are correct: 
-     *  because we recycle and never free schedule structs it's
-     *  actually OK to try and delete a schedule that has been executed... */
+     * it's perfectly OK to delete a schedule that has been executed,
+     * we're just marking the schedule as deleted here so that it can be
+     * cleaned up by doscheduledevents later on. */
      
-    if (sp->callback==callback && sp->callbackparam==arg) {
+    if (sp->callback==callback && sp->callbackparam==arg && !sp->deleted) {
       scheddelfast++;
-      schedule_remove(sp->index);
-      freeschedule(sp);
+      sp->deleted=1;
+#ifdef SCHEDDEBUG
+    } else {
+      Error("schedule",ERR_DEBUG,"deleted schedule that was previously marked as deleted");
+#endif
     }
     return;
   }
@@ -221,10 +231,9 @@ void deleteschedule(void *sch, ScheduleCallback callback, void *arg) {
   /* Argh, have to find it by brute force */
 
   for(i=0;i<heapsize;i++) {
-    if ((events[i]->callback==callback) && (events[i]->callbackparam==arg)) {
+    if (events[i]->callback==callback && events[i]->callbackparam==arg && !events[i]->deleted) {
       sp=events[i];
-      schedule_remove(sp->index);
-      freeschedule(sp);
+      sp->deleted=1;
       return;
     }
   }
@@ -262,9 +271,15 @@ void doscheduledevents(time_t when) {
     events[0]=events[heapsize];
     events[0]->index=0;
     schedule_heapify(0);
-    
+
+    /* This schedule was previously marked as deleted and we're now lazily cleaning it up. */
+    if (sp->deleted) {
+      freeschedule(sp);
+      continue;
+    } 
+   
     if (sp->callback==NULL) {
-      Error("core",ERR_ERROR,"Tried to call NULL function in doscheduledevents(): (%x, %x, %x)",sp,sp->callback,sp->callbackparam);
+      Error("core",ERR_ERROR,"Tried to call NULL function in doscheduledevents(): (%p, %p, %p)",sp,sp->callback,sp->callbackparam);
       continue;
     }
 
@@ -275,7 +290,7 @@ void doscheduledevents(time_t when) {
     /* Update the structures _before_ doing the callback.. */
     switch(sp->type) {
     case SCHEDULE_ONESHOT:
-      freeschedule(sp);
+      sp->deleted=1;
       break;
         
     case SCHEDULE_REPEATING:
@@ -292,11 +307,13 @@ void doscheduledevents(time_t when) {
          sp->type=SCHEDULE_ONESHOT;       
        }
       }
-      insertschedule(sp);
       break;
     }
+
+    insertschedule(sp);
+
 #ifdef SCHEDDEBUG
-    Error("schedule",ERR_DEBUG,"exec schedule:(%x, %x, %x)", sp, sc, arg);
+    Error("schedule",ERR_DEBUG,"exec schedule:(%x, %x, %x)", (unsigned int)sp, (unsigned int)sc, (unsigned int)arg);
 #endif
     (sc)(arg);
 #ifdef SCHEDDEBUG