aboutsummaryrefslogtreecommitdiff
path: root/src/core/or/orconn_event.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-12-21 14:22:11 -0500
committerNick Mathewson <nickm@torproject.org>2018-12-21 14:22:11 -0500
commit70dd6d07bbd7c233e9f39e24b27775eae77f2363 (patch)
treedcef8cb65c5599e19ccb8b1f086eb1b792b6a8ee /src/core/or/orconn_event.c
parentfd58e5e498f1c86732de8d9edf6777e7822abfe7 (diff)
parent2100b35f0799276f9854dd625621deda33a9ecc3 (diff)
downloadtor-70dd6d07bbd7c233e9f39e24b27775eae77f2363.tar.gz
tor-70dd6d07bbd7c233e9f39e24b27775eae77f2363.zip
Merge branch 'orconn-tracker_squashed'
Diffstat (limited to 'src/core/or/orconn_event.c')
-rw-r--r--src/core/or/orconn_event.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/core/or/orconn_event.c b/src/core/or/orconn_event.c
new file mode 100644
index 0000000000..d81f7b5a0c
--- /dev/null
+++ b/src/core/or/orconn_event.c
@@ -0,0 +1,81 @@
+/* Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file orconn_event.c
+ * \brief Publish state change messages for OR connections
+ *
+ * Implements a basic publish-subscribe framework for messages about
+ * the state of OR connections. The publisher calls the subscriber
+ * callback functions synchronously.
+ *
+ * Although the synchronous calls might not simplify the call graph,
+ * this approach improves data isolation because the publisher doesn't
+ * need knowledge about the internals of subscribing subsystems. It
+ * also avoids race conditions that might occur in asynchronous
+ * frameworks.
+ **/
+
+#include "core/or/or.h"
+#include "lib/subsys/subsys.h"
+
+#define ORCONN_EVENT_PRIVATE
+#include "core/or/orconn_event.h"
+#include "core/or/orconn_event_sys.h"
+
+/** List of subscribers */
+static smartlist_t *orconn_event_rcvrs;
+
+/** Initialize subscriber list */
+static int
+orconn_event_init(void)
+{
+ orconn_event_rcvrs = smartlist_new();
+ return 0;
+}
+
+/** Free subscriber list */
+static void
+orconn_event_fini(void)
+{
+ smartlist_free(orconn_event_rcvrs);
+}
+
+/**
+ * Subscribe to messages about OR connection events
+ *
+ * Register a callback function to receive messages about ORCONNs.
+ * The publisher calls this function synchronously.
+ **/
+void
+orconn_event_subscribe(orconn_event_rcvr_t fn)
+{
+ tor_assert(fn);
+ /* Don't duplicate subscriptions. */
+ if (smartlist_contains(orconn_event_rcvrs, fn))
+ return;
+
+ smartlist_add(orconn_event_rcvrs, fn);
+}
+
+/**
+ * Publish a message about OR connection events
+ *
+ * This calls the subscriber receiver function synchronously.
+ **/
+void
+orconn_event_publish(const orconn_event_msg_t *msg)
+{
+ SMARTLIST_FOREACH_BEGIN(orconn_event_rcvrs, orconn_event_rcvr_t, fn) {
+ tor_assert(fn);
+ (*fn)(msg);
+ } SMARTLIST_FOREACH_END(fn);
+}
+
+const subsys_fns_t sys_orconn_event = {
+ .name = "orconn_event",
+ .supported = true,
+ .level = -33,
+ .initialize = orconn_event_init,
+ .shutdown = orconn_event_fini,
+};