aboutsummaryrefslogtreecommitdiff
path: root/src/or/periodic.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/periodic.c')
-rw-r--r--src/or/periodic.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/src/or/periodic.c b/src/or/periodic.c
index 42bea3ae65..76aa418b35 100644
--- a/src/or/periodic.c
+++ b/src/or/periodic.c
@@ -43,12 +43,22 @@ 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);
const or_options_t *options = get_options();
// log_debug(LD_GENERAL, "Dispatching %s", event->name);
int r = event->fn(now, options);
int next_interval = 0;
+ if (!periodic_event_is_enabled(event)) {
+ /* The event got disabled from inside its callback; no need to
+ * reschedule. */
+ return;
+ }
+
/* update the last run time if action was taken */
if (r==0) {
log_err(LD_BUG, "Invalid return value for periodic event from %s.",
@@ -114,8 +124,8 @@ periodic_event_launch(periodic_event_item_t *event)
}
// Initial dispatch
- periodic_event_dispatch(event->ev, event);
event->enabled = 1;
+ periodic_event_dispatch(event->ev, event);
}
/** Release all storage associated with <b>event</b> */
@@ -126,6 +136,35 @@ periodic_event_destroy(periodic_event_item_t *event)
return;
mainloop_event_free(event->ev);
event->last_action_time = 0;
+}
+
+/** Enable the given event which means the event is launched and then the
+ * event's enabled flag is set. This can be called for an event that is
+ * already enabled. */
+void
+periodic_event_enable(periodic_event_item_t *event)
+{
+ tor_assert(event);
+ /* Safely and silently ignore if this event is already enabled. */
+ if (periodic_event_is_enabled(event)) {
+ return;
+ }
+
+ periodic_event_launch(event);
+}
+
+/** Disable the given event which means the event is destroyed and then the
+ * event's enabled flag is unset. This can be called for an event that is
+ * already disabled. */
+void
+periodic_event_disable(periodic_event_item_t *event)
+{
+ tor_assert(event);
+ /* Safely and silently ignore if this event is already disabled. */
+ if (!periodic_event_is_enabled(event)) {
+ return;
+ }
+ mainloop_event_cancel(event->ev);
event->enabled = 0;
}