Merge branch 'orconn-tracker_squashed'
[tor.git] / src / core / or / orconn_event.c
blobd81f7b5a0c7ca2132231515acbd7a52e16ccf236
1 /* Copyright (c) 2007-2018, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 /**
5 * \file orconn_event.c
6 * \brief Publish state change messages for OR connections
8 * Implements a basic publish-subscribe framework for messages about
9 * the state of OR connections. The publisher calls the subscriber
10 * callback functions synchronously.
12 * Although the synchronous calls might not simplify the call graph,
13 * this approach improves data isolation because the publisher doesn't
14 * need knowledge about the internals of subscribing subsystems. It
15 * also avoids race conditions that might occur in asynchronous
16 * frameworks.
17 **/
19 #include "core/or/or.h"
20 #include "lib/subsys/subsys.h"
22 #define ORCONN_EVENT_PRIVATE
23 #include "core/or/orconn_event.h"
24 #include "core/or/orconn_event_sys.h"
26 /** List of subscribers */
27 static smartlist_t *orconn_event_rcvrs;
29 /** Initialize subscriber list */
30 static int
31 orconn_event_init(void)
33 orconn_event_rcvrs = smartlist_new();
34 return 0;
37 /** Free subscriber list */
38 static void
39 orconn_event_fini(void)
41 smartlist_free(orconn_event_rcvrs);
44 /**
45 * Subscribe to messages about OR connection events
47 * Register a callback function to receive messages about ORCONNs.
48 * The publisher calls this function synchronously.
49 **/
50 void
51 orconn_event_subscribe(orconn_event_rcvr_t fn)
53 tor_assert(fn);
54 /* Don't duplicate subscriptions. */
55 if (smartlist_contains(orconn_event_rcvrs, fn))
56 return;
58 smartlist_add(orconn_event_rcvrs, fn);
61 /**
62 * Publish a message about OR connection events
64 * This calls the subscriber receiver function synchronously.
65 **/
66 void
67 orconn_event_publish(const orconn_event_msg_t *msg)
69 SMARTLIST_FOREACH_BEGIN(orconn_event_rcvrs, orconn_event_rcvr_t, fn) {
70 tor_assert(fn);
71 (*fn)(msg);
72 } SMARTLIST_FOREACH_END(fn);
75 const subsys_fns_t sys_orconn_event = {
76 .name = "orconn_event",
77 .supported = true,
78 .level = -33,
79 .initialize = orconn_event_init,
80 .shutdown = orconn_event_fini,