]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Add a function to schedule a periodic event once, then disable it
authorNick Mathewson <nickm@torproject.org>
Mon, 5 Nov 2018 21:24:10 +0000 (16:24 -0500)
committerNick Mathewson <nickm@torproject.org>
Thu, 15 Nov 2018 16:17:22 +0000 (11:17 -0500)
src/core/mainloop/mainloop.c
src/core/mainloop/periodic.c
src/core/mainloop/periodic.h

index 12820888f254f5fab3c11d8d923f894b9fa93381..42f6fb50c72a7c8fb265d95a2b2c2b8f0fba2bf7 100644 (file)
@@ -1600,7 +1600,11 @@ rescan_periodic_events(const or_options_t *options)
       periodic_event_enable(item);
     } else {
       log_debug(LD_GENERAL, "Disabling periodic event %s", item->name);
-      periodic_event_disable(item);
+      if (item->flags & PERIODIC_EVENT_FLAG_FLUSH_ON_DISABLE) {
+        periodic_event_flush_and_disable(item);
+      } else {
+        periodic_event_disable(item);
+      }
     }
   }
 }
index c1785eb38f34129a9240b6de55e1970040c94a10..c290c3744ed32afd2bacea602d9765b22d172bb1 100644 (file)
@@ -45,10 +45,6 @@ periodic_event_dispatch(mainloop_event_t *ev, void *data)
   periodic_event_item_t *event = data;
   tor_assert(ev == event->ev);
 
-  if (BUG(!periodic_event_is_enabled(event))) {
-    return;
-  }
-
   time_t now = time(NULL);
   update_current_time(now);
   const or_options_t *options = get_options();
@@ -57,7 +53,7 @@ periodic_event_dispatch(mainloop_event_t *ev, void *data)
   int next_interval = 0;
 
   if (!periodic_event_is_enabled(event)) {
-    /* The event got disabled from inside its callback; no need to
+    /* The event got disabled from inside its callback, or before: no need to
      * reschedule. */
     return;
   }
@@ -172,3 +168,19 @@ periodic_event_disable(periodic_event_item_t *event)
   mainloop_event_cancel(event->ev);
   event->enabled = 0;
 }
+
+/**
+ * Disable an event, then schedule it to run once.
+ * Do nothing if the event was already disabled.
+ */
+void
+periodic_event_flush_and_disable(periodic_event_item_t *event)
+{
+  tor_assert(event);
+  if (!periodic_event_is_enabled(event))
+    return;
+
+  periodic_event_disable(event);
+
+  mainloop_event_activate(event->ev);
+}
index 4c8c3c96cce33b23c0484e380bee2ebb441a3c68..7c71be7bc405269b8a93f19dd43e5afa71889966 100644 (file)
  * the net_is_disabled() check. */
 #define PERIODIC_EVENT_FLAG_NEED_NET  (1U << 0)
 
+/* Indicate that it the event is enabled, it event needs to be run once before
+ * it becomes disabled.
+ */
+#define PERIODIC_EVENT_FLAG_FLUSH_ON_DISABLE  (1U << 1)
+
 /** Callback function for a periodic event to take action.  The return value
 * influences the next time the function will get called.  Return
 * PERIODIC_EVENT_NO_UPDATE to not update <b>last_action_time</b> and be polled
@@ -83,6 +88,6 @@ void periodic_event_destroy(periodic_event_item_t *event);
 void periodic_event_reschedule(periodic_event_item_t *event);
 void periodic_event_enable(periodic_event_item_t *event);
 void periodic_event_disable(periodic_event_item_t *event);
+void periodic_event_flush_and_disable(periodic_event_item_t *event);
 
 #endif /* !defined(TOR_PERIODIC_H) */
-