diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-12-21 14:22:11 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-12-21 14:22:11 -0500 |
commit | 70dd6d07bbd7c233e9f39e24b27775eae77f2363 (patch) | |
tree | dcef8cb65c5599e19ccb8b1f086eb1b792b6a8ee /src/core/or/orconn_event.c | |
parent | fd58e5e498f1c86732de8d9edf6777e7822abfe7 (diff) | |
parent | 2100b35f0799276f9854dd625621deda33a9ecc3 (diff) | |
download | tor-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.c | 81 |
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, +}; |