periodic.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. /* Copyright (c) 2015-2019, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file periodic.c
  5. *
  6. * \brief Generic backend for handling periodic events.
  7. *
  8. * The events in this module are used to track items that need
  9. * to fire once every N seconds, possibly picking a new interval each time
  10. * that they fire. See periodic_events[] in mainloop.c for examples.
  11. *
  12. * This module manages a global list of periodic_event_item_t objects,
  13. * each corresponding to a single event. To register an event, pass it to
  14. * periodic_events_register() when initializing your subsystem.
  15. *
  16. * Registering an event makes the periodic event subsystem know about it, but
  17. * doesn't cause the event to get created immediately. Before the event can
  18. * be started, periodic_event_connect_all() must be called by mainloop.c to
  19. * connect all the events to Libevent.
  20. *
  21. * We expect that periodic_event_item_t objects will be statically allocated;
  22. * we set them up and tear them down here, but we don't take ownership of
  23. * them.
  24. */
  25. #include "core/or/or.h"
  26. #include "lib/evloop/compat_libevent.h"
  27. #include "app/config/config.h"
  28. #include "core/mainloop/mainloop.h"
  29. #include "core/mainloop/periodic.h"
  30. #include "lib/evloop/compat_libevent.h"
  31. /** We disable any interval greater than this number of seconds, on the
  32. * grounds that it is probably an absolute time mistakenly passed in as a
  33. * relative time.
  34. */
  35. static const int MAX_INTERVAL = 10 * 365 * 86400;
  36. /**
  37. * Global list of periodic events that have been registered with
  38. * <b>periodic_event_register</a>.
  39. **/
  40. static smartlist_t *the_periodic_events = NULL;
  41. /** Set the event <b>event</b> to run in <b>next_interval</b> seconds from
  42. * now. */
  43. static void
  44. periodic_event_set_interval(periodic_event_item_t *event,
  45. time_t next_interval)
  46. {
  47. tor_assert(next_interval < MAX_INTERVAL);
  48. struct timeval tv;
  49. tv.tv_sec = next_interval;
  50. tv.tv_usec = 0;
  51. mainloop_event_schedule(event->ev, &tv);
  52. }
  53. /** Wraps dispatches for periodic events, <b>data</b> will be a pointer to the
  54. * event that needs to be called */
  55. static void
  56. periodic_event_dispatch(mainloop_event_t *ev, void *data)
  57. {
  58. periodic_event_item_t *event = data;
  59. tor_assert(ev == event->ev);
  60. time_t now = time(NULL);
  61. update_current_time(now);
  62. const or_options_t *options = get_options();
  63. // log_debug(LD_GENERAL, "Dispatching %s", event->name);
  64. int r = event->fn(now, options);
  65. int next_interval = 0;
  66. if (!periodic_event_is_enabled(event)) {
  67. /* The event got disabled from inside its callback, or before: no need to
  68. * reschedule. */
  69. return;
  70. }
  71. /* update the last run time if action was taken */
  72. if (r==0) {
  73. log_err(LD_BUG, "Invalid return value for periodic event from %s.",
  74. event->name);
  75. tor_assert(r != 0);
  76. } else if (r > 0) {
  77. event->last_action_time = now;
  78. /* If the event is meant to happen after ten years, that's likely
  79. * a bug, and somebody gave an absolute time rather than an interval.
  80. */
  81. tor_assert(r < MAX_INTERVAL);
  82. next_interval = r;
  83. } else {
  84. /* no action was taken, it is likely a precondition failed,
  85. * we should reschedule for next second incase the precondition
  86. * passes then */
  87. next_interval = 1;
  88. }
  89. // log_debug(LD_GENERAL, "Scheduling %s for %d seconds", event->name,
  90. // next_interval);
  91. struct timeval tv = { next_interval , 0 };
  92. mainloop_event_schedule(ev, &tv);
  93. }
  94. /** Schedules <b>event</b> to run as soon as possible from now. */
  95. void
  96. periodic_event_reschedule(periodic_event_item_t *event)
  97. {
  98. /* Don't reschedule a disabled or uninitialized event. */
  99. if (event->ev && periodic_event_is_enabled(event)) {
  100. periodic_event_set_interval(event, 1);
  101. }
  102. }
  103. /** Connects a periodic event to the Libevent backend. Does not launch the
  104. * event immediately. */
  105. void
  106. periodic_event_connect(periodic_event_item_t *event)
  107. {
  108. if (event->ev) { /* Already setup? This is a bug */
  109. log_err(LD_BUG, "Initial dispatch should only be done once.");
  110. tor_assert(0);
  111. }
  112. event->ev = mainloop_event_new(periodic_event_dispatch,
  113. event);
  114. tor_assert(event->ev);
  115. }
  116. /** Handles initial dispatch for periodic events. It should happen 1 second
  117. * after the events are created to mimic behaviour before #3199's refactor */
  118. void
  119. periodic_event_launch(periodic_event_item_t *event)
  120. {
  121. if (! event->ev) { /* Not setup? This is a bug */
  122. log_err(LD_BUG, "periodic_event_launch without periodic_event_connect");
  123. tor_assert(0);
  124. }
  125. /* Event already enabled? This is a bug */
  126. if (periodic_event_is_enabled(event)) {
  127. log_err(LD_BUG, "periodic_event_launch on an already enabled event");
  128. tor_assert(0);
  129. }
  130. // Initial dispatch
  131. event->enabled = 1;
  132. periodic_event_dispatch(event->ev, event);
  133. }
  134. /** Disconnect and unregister the periodic event in <b>event</b> */
  135. static void
  136. periodic_event_disconnect(periodic_event_item_t *event)
  137. {
  138. if (!event)
  139. return;
  140. /* First disable the event so we first cancel the event and set its enabled
  141. * flag properly. */
  142. periodic_event_disable(event);
  143. mainloop_event_free(event->ev);
  144. event->last_action_time = 0;
  145. }
  146. /** Enable the given event by setting its "enabled" flag and scheduling it to
  147. * run immediately in the event loop. This can be called for an event that is
  148. * already enabled. */
  149. void
  150. periodic_event_enable(periodic_event_item_t *event)
  151. {
  152. tor_assert(event);
  153. /* Safely and silently ignore if this event is already enabled. */
  154. if (periodic_event_is_enabled(event)) {
  155. return;
  156. }
  157. tor_assert(event->ev);
  158. event->enabled = 1;
  159. mainloop_event_activate(event->ev);
  160. }
  161. /** Disable the given event which means the event is destroyed and then the
  162. * event's enabled flag is unset. This can be called for an event that is
  163. * already disabled. */
  164. void
  165. periodic_event_disable(periodic_event_item_t *event)
  166. {
  167. tor_assert(event);
  168. /* Safely and silently ignore if this event is already disabled. */
  169. if (!periodic_event_is_enabled(event)) {
  170. return;
  171. }
  172. mainloop_event_cancel(event->ev);
  173. event->enabled = 0;
  174. }
  175. /**
  176. * Disable an event, then schedule it to run once.
  177. * Do nothing if the event was already disabled.
  178. */
  179. void
  180. periodic_event_schedule_and_disable(periodic_event_item_t *event)
  181. {
  182. tor_assert(event);
  183. if (!periodic_event_is_enabled(event))
  184. return;
  185. periodic_event_disable(event);
  186. mainloop_event_activate(event->ev);
  187. }
  188. /**
  189. * Add <b>item</b> to the list of periodic events.
  190. *
  191. * Note that <b>item</b> should be statically allocated: we do not
  192. * take ownership of it.
  193. **/
  194. void
  195. periodic_events_register(periodic_event_item_t *item)
  196. {
  197. if (!the_periodic_events)
  198. the_periodic_events = smartlist_new();
  199. if (BUG(smartlist_contains(the_periodic_events, item)))
  200. return;
  201. smartlist_add(the_periodic_events, item);
  202. }
  203. /**
  204. * Make all registered periodic events connect to the libevent backend.
  205. */
  206. void
  207. periodic_events_connect_all(void)
  208. {
  209. if (! the_periodic_events)
  210. return;
  211. SMARTLIST_FOREACH_BEGIN(the_periodic_events, periodic_event_item_t *, item) {
  212. if (item->ev)
  213. continue;
  214. periodic_event_connect(item);
  215. } SMARTLIST_FOREACH_END(item);
  216. }
  217. /**
  218. * Reset all the registered periodic events so we'll do all our actions again
  219. * as if we just started up.
  220. *
  221. * Useful if our clock just moved back a long time from the future,
  222. * so we don't wait until that future arrives again before acting.
  223. */
  224. void
  225. periodic_events_reset_all(void)
  226. {
  227. if (! the_periodic_events)
  228. return;
  229. SMARTLIST_FOREACH_BEGIN(the_periodic_events, periodic_event_item_t *, item) {
  230. if (!item->ev)
  231. continue;
  232. periodic_event_reschedule(item);
  233. } SMARTLIST_FOREACH_END(item);
  234. }
  235. /**
  236. * Return the registered periodic event whose name is <b>name</b>.
  237. * Return NULL if no such event is found.
  238. */
  239. periodic_event_item_t *
  240. periodic_events_find(const char *name)
  241. {
  242. if (! the_periodic_events)
  243. return NULL;
  244. SMARTLIST_FOREACH_BEGIN(the_periodic_events, periodic_event_item_t *, item) {
  245. if (strcmp(name, item->name) == 0)
  246. return item;
  247. } SMARTLIST_FOREACH_END(item);
  248. return NULL;
  249. }
  250. /**
  251. * Start or stop registered periodic events, depending on our current set of
  252. * roles.
  253. *
  254. * Invoked when our list of roles, or the net_disabled flag has changed.
  255. **/
  256. void
  257. periodic_events_rescan_by_roles(int roles, bool net_disabled)
  258. {
  259. if (! the_periodic_events)
  260. return;
  261. SMARTLIST_FOREACH_BEGIN(the_periodic_events, periodic_event_item_t *, item) {
  262. if (!item->ev)
  263. continue;
  264. int enable = !!(item->roles & roles);
  265. /* Handle the event flags. */
  266. if (net_disabled &&
  267. (item->flags & PERIODIC_EVENT_FLAG_NEED_NET)) {
  268. enable = 0;
  269. }
  270. /* Enable the event if needed. It is safe to enable an event that was
  271. * already enabled. Same goes for disabling it. */
  272. if (enable) {
  273. log_debug(LD_GENERAL, "Launching periodic event %s", item->name);
  274. periodic_event_enable(item);
  275. } else {
  276. log_debug(LD_GENERAL, "Disabling periodic event %s", item->name);
  277. if (item->flags & PERIODIC_EVENT_FLAG_RUN_ON_DISABLE) {
  278. periodic_event_schedule_and_disable(item);
  279. } else {
  280. periodic_event_disable(item);
  281. }
  282. }
  283. } SMARTLIST_FOREACH_END(item);
  284. }
  285. /**
  286. * Invoked at shutdown: disconnect and unregister all periodic events.
  287. *
  288. * Does not free the periodic_event_item_t object themselves, because we do
  289. * not own them.
  290. */
  291. void
  292. periodic_events_disconnect_all(void)
  293. {
  294. if (! the_periodic_events)
  295. return;
  296. SMARTLIST_FOREACH_BEGIN(the_periodic_events, periodic_event_item_t *, item) {
  297. periodic_event_disconnect(item);
  298. } SMARTLIST_FOREACH_END(item);
  299. smartlist_free(the_periodic_events);
  300. }
  301. #define LONGEST_TIMER_PERIOD (30 * 86400)
  302. /** Helper: Return the number of seconds between <b>now</b> and <b>next</b>,
  303. * clipped to the range [1 second, LONGEST_TIMER_PERIOD].
  304. *
  305. * We use this to answer the question, "how many seconds is it from now until
  306. * next" in periodic timer callbacks. Don't use it for other purposes
  307. **/
  308. int
  309. safe_timer_diff(time_t now, time_t next)
  310. {
  311. if (next > now) {
  312. /* There were no computers at signed TIME_MIN (1902 on 32-bit systems),
  313. * and nothing that could run Tor. It's a bug if 'next' is around then.
  314. * On 64-bit systems with signed TIME_MIN, TIME_MIN is before the Big
  315. * Bang. We cannot extrapolate past a singularity, but there was probably
  316. * nothing that could run Tor then, either.
  317. **/
  318. tor_assert(next > TIME_MIN + LONGEST_TIMER_PERIOD);
  319. if (next - LONGEST_TIMER_PERIOD > now)
  320. return LONGEST_TIMER_PERIOD;
  321. return (int)(next - now);
  322. } else {
  323. return 1;
  324. }
  325. }