ocirc_event.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /* Copyright (c) 2007-2019, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file ocirc_event.c
  5. * \brief Publish state change messages for origin circuits
  6. *
  7. * Implements a basic publish-subscribe framework for messages about
  8. * the state of origin circuits. The publisher calls the subscriber
  9. * callback functions synchronously.
  10. *
  11. * Although the synchronous calls might not simplify the call graph,
  12. * this approach improves data isolation because the publisher doesn't
  13. * need knowledge about the internals of subscribing subsystems. It
  14. * also avoids race conditions that might occur in asynchronous
  15. * frameworks.
  16. **/
  17. #include "core/or/or.h"
  18. #define OCIRC_EVENT_PRIVATE
  19. #include "core/or/cpath_build_state_st.h"
  20. #include "core/or/ocirc_event.h"
  21. #include "core/or/ocirc_event_sys.h"
  22. #include "core/or/origin_circuit_st.h"
  23. #include "lib/subsys/subsys.h"
  24. /** List of subscribers */
  25. static smartlist_t *ocirc_event_rcvrs;
  26. /** Initialize subscriber list */
  27. static int
  28. ocirc_event_init(void)
  29. {
  30. ocirc_event_rcvrs = smartlist_new();
  31. return 0;
  32. }
  33. /** Free subscriber list */
  34. static void
  35. ocirc_event_fini(void)
  36. {
  37. smartlist_free(ocirc_event_rcvrs);
  38. }
  39. /**
  40. * Subscribe to messages about origin circuit events
  41. *
  42. * Register a callback function to receive messages about origin
  43. * circuits. The publisher calls this function synchronously.
  44. **/
  45. void
  46. ocirc_event_subscribe(ocirc_event_rcvr_t fn)
  47. {
  48. tor_assert(fn);
  49. /* Don't duplicate subscriptions. */
  50. if (smartlist_contains(ocirc_event_rcvrs, fn))
  51. return;
  52. smartlist_add(ocirc_event_rcvrs, fn);
  53. }
  54. /**
  55. * Publish a message about OR connection events
  56. *
  57. * This calls the subscriber receiver function synchronously.
  58. **/
  59. void
  60. ocirc_event_publish(const ocirc_event_msg_t *msg)
  61. {
  62. SMARTLIST_FOREACH_BEGIN(ocirc_event_rcvrs, ocirc_event_rcvr_t, fn) {
  63. tor_assert(fn);
  64. (*fn)(msg);
  65. } SMARTLIST_FOREACH_END(fn);
  66. }
  67. const subsys_fns_t sys_ocirc_event = {
  68. .name = "ocirc_event",
  69. .supported = true,
  70. .level = -32,
  71. .initialize = ocirc_event_init,
  72. .shutdown = ocirc_event_fini,
  73. };