소스 검색

Merge branch 'bug3199_redux_3'

Nick Mathewson 10 년 전
부모
커밋
c113d19b53
4개의 변경된 파일714개의 추가작업 그리고 318개의 파일을 삭제
  1. 2 0
      src/or/include.am
  2. 566 318
      src/or/main.c
  3. 110 0
      src/or/periodic.c
  4. 36 0
      src/or/periodic.h

+ 2 - 0
src/or/include.am

@@ -63,6 +63,7 @@ LIBTOR_A_SOURCES = \
 	src/or/onion_fast.c				\
 	src/or/onion_tap.c				\
 	src/or/transports.c				\
+	src/or/periodic.c				\
 	src/or/policies.c				\
 	src/or/reasons.c				\
 	src/or/relay.c					\
@@ -173,6 +174,7 @@ ORHEADERS = \
 	src/or/onion_tap.h				\
 	src/or/or.h					\
 	src/or/transports.h				\
+	src/or/periodic.h				\
 	src/or/policies.h				\
 	src/or/reasons.h				\
 	src/or/relay.h					\

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 566 - 318
src/or/main.c


+ 110 - 0
src/or/periodic.c

@@ -0,0 +1,110 @@
+/* Copyright (c) 2015, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "or.h"
+#include "compat_libevent.h"
+#include "config.h"
+#include "periodic.h"
+
+#ifdef HAVE_EVENT2_EVENT_H
+#include <event2/event.h>
+#else
+#include <event.h>
+#endif
+
+/** We disable any interval greater than this number of seconds, on the
+ * grounds that it is probably an absolute time mistakenly passed in as a
+ * relative time.
+ */
+static const int MAX_INTERVAL = 10 * 365 * 86400;
+
+/** Set the event <b>event</b> to run in <b>next_interval</b> seconds from
+ * now. */
+static void
+periodic_event_set_interval(periodic_event_item_t *event,
+                            time_t next_interval)
+{
+  tor_assert(next_interval < MAX_INTERVAL);
+  struct timeval tv;
+  tv.tv_sec = next_interval;
+  tv.tv_usec = 0;
+  event_add(event->ev, &tv);
+}
+
+/** Wraps dispatches for periodic events, <b>data</b> will be a pointer to the
+ * event that needs to be called */
+static void
+periodic_event_dispatch(evutil_socket_t fd, short what, void *data)
+{
+  (void)fd;
+  (void)what;
+  periodic_event_item_t *event = data;
+
+  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;
+
+  /* update the last run time if action was taken */
+  if (r==0) {
+    log_err(LD_BUG, "Invalid return value for periodic event from %s.",
+                      event->name);
+    tor_assert(r != 0);
+  } else if (r > 0) {
+    event->last_action_time = now;
+    /* If the event is meant to happen after ten years, that's likely
+     * a bug, and somebody gave an absolute time rather than an interval.
+     */
+    tor_assert(r < MAX_INTERVAL);
+    next_interval = r;
+  } else {
+    /* no action was taken, it is likely a precondition failed,
+     * we should reschedule for next second incase the precondition
+     * passes then */
+    next_interval = 1;
+  }
+
+  log_debug(LD_GENERAL, "Scheduling %s for %d seconds", event->name,
+           next_interval);
+  struct timeval tv = { next_interval , 0 };
+  event_add(event->ev, &tv);
+}
+
+/** Schedules <b>event</b> to run as soon as possible from now. */
+void
+periodic_event_reschedule(periodic_event_item_t *event)
+{
+  periodic_event_set_interval(event, 1);
+}
+
+/** Handles initial dispatch for periodic events. It should happen 1 second
+ * after the events are created to mimic behaviour before #3199's refactor */
+void
+periodic_event_launch(periodic_event_item_t *event)
+{
+  if (event->ev) { /** Already setup? This is a bug */
+    log_err(LD_BUG, "Initial dispatch should only be done once.");
+    tor_assert(0);
+  }
+
+  event->ev = tor_event_new(tor_libevent_get_base(),
+                            -1, 0,
+                            periodic_event_dispatch,
+                            event);
+  tor_assert(event->ev);
+
+  // Initial dispatch
+  periodic_event_dispatch(-1, EV_TIMEOUT, event);
+}
+
+/** Release all storage associated with <b>event</b> */
+void
+periodic_event_destroy(periodic_event_item_t *event)
+{
+  if (!event)
+    return;
+  tor_event_free(event->ev);
+  event->last_action_time = 0;
+}
+

+ 36 - 0
src/or/periodic.h

@@ -0,0 +1,36 @@
+/* Copyright (c) 2015, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_PERIODIC_H
+#define TOR_PERIODIC_H
+
+#define PERIODIC_EVENT_NO_UPDATE (-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
+* again in the next second. If a positive value is returned it will update the
+* interval time. */
+typedef int (*periodic_event_helper_t)(time_t now,
+                                      const or_options_t *options);
+
+struct event;
+
+/** A single item for the periodic-events-function table. */
+typedef struct periodic_event_item_t {
+  periodic_event_helper_t fn; /**< The function to run the event */
+  time_t last_action_time; /**< The last time the function did something */
+  struct event *ev; /**< Libevent callback we're using to implement this */
+  const char *name; /**< Name of the function -- for debug */
+} periodic_event_item_t;
+
+/** events will get their interval from first execution */
+#define PERIODIC_EVENT(fn) { fn##_callback, 0, NULL, #fn }
+#define END_OF_PERIODIC_EVENTS { NULL, 0, NULL, NULL }
+
+void periodic_event_launch(periodic_event_item_t *event);
+void periodic_event_destroy(periodic_event_item_t *event);
+void periodic_event_reschedule(periodic_event_item_t *event);
+
+#endif
+

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.