123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- /* Copyright (c) 2007-2019, The Tor Project, Inc. */
- /* See LICENSE for licensing information */
- /**
- * \file ocirc_event.c
- * \brief Publish state change messages for origin circuits
- *
- * Implements a basic publish-subscribe framework for messages about
- * the state of origin circuits. 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"
- #define OCIRC_EVENT_PRIVATE
- #include "core/or/cpath_build_state_st.h"
- #include "core/or/ocirc_event.h"
- #include "core/or/ocirc_event_sys.h"
- #include "core/or/origin_circuit_st.h"
- #include "lib/subsys/subsys.h"
- /** List of subscribers */
- static smartlist_t *ocirc_event_rcvrs;
- /** Initialize subscriber list */
- static int
- ocirc_event_init(void)
- {
- ocirc_event_rcvrs = smartlist_new();
- return 0;
- }
- /** Free subscriber list */
- static void
- ocirc_event_fini(void)
- {
- smartlist_free(ocirc_event_rcvrs);
- }
- /**
- * Subscribe to messages about origin circuit events
- *
- * Register a callback function to receive messages about origin
- * circuits. The publisher calls this function synchronously.
- **/
- void
- ocirc_event_subscribe(ocirc_event_rcvr_t fn)
- {
- tor_assert(fn);
- /* Don't duplicate subscriptions. */
- if (smartlist_contains(ocirc_event_rcvrs, fn))
- return;
- smartlist_add(ocirc_event_rcvrs, fn);
- }
- /**
- * Publish a message about OR connection events
- *
- * This calls the subscriber receiver function synchronously.
- **/
- void
- ocirc_event_publish(const ocirc_event_msg_t *msg)
- {
- SMARTLIST_FOREACH_BEGIN(ocirc_event_rcvrs, ocirc_event_rcvr_t, fn) {
- tor_assert(fn);
- (*fn)(msg);
- } SMARTLIST_FOREACH_END(fn);
- }
- const subsys_fns_t sys_ocirc_event = {
- .name = "ocirc_event",
- .supported = true,
- .level = -32,
- .initialize = ocirc_event_init,
- .shutdown = ocirc_event_fini,
- };
|