dispatch.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /* Copyright (c) 2001, Matej Pfajfar.
  2. * Copyright (c) 2001-2004, Roger Dingledine.
  3. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  4. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. #ifndef TOR_DISPATCH_H
  7. #define TOR_DISPATCH_H
  8. #include "lib/dispatch/msgtypes.h"
  9. /**
  10. * \file dispatch.h
  11. * \brief Low-level APIs for message-passing system.
  12. *
  13. * This module implements message dispatch based on a set of short integer
  14. * identifiers. For a higher-level interface, see pubsub.h.
  15. *
  16. * Each message is represented as a generic msg_t object, and is discriminated
  17. * by its message_id_t. Messages are delivered by a dispatch_t object, which
  18. * delivers each message to its recipients by a configured "channel".
  19. *
  20. * A "channel" is a means of delivering messages. Every message_id_t must
  21. * be associated with exactly one channel, identified by channel_id_t.
  22. * When a channel receives messages, a callback is invoked to either process
  23. * the messages immediately, or to cause them to be processed later.
  24. *
  25. * Every message_id_t has zero or more associated receiver functions set up in
  26. * the dispatch_t object. Once the dispatch_t object is created, receivers
  27. * can be enabled or disabled [TODO], but not added or removed.
  28. *
  29. * Every message_id_t has an associated datatype, identified by a
  30. * msg_type_id_t. These datatypes can be associated with functions to
  31. * (for example) free them, or format them for debugging.
  32. *
  33. * To setup a dispatch_t object, first create a dispatch_cfg_t object, and
  34. * configure messages with their types, channels, and receivers. Then, use
  35. * dispatch_new() with that dispatch_cfg_t to create the dispatch_t object.
  36. *
  37. * (We use a two-phase contruction procedure here to enable better static
  38. * reasoning about publish/subscribe relationships.)
  39. *
  40. * Once you have a dispatch_t, you can queue messages on it with
  41. * dispatch_send*(), and cause those messages to be delivered with
  42. * dispatch_flush().
  43. **/
  44. /**
  45. * A "dispatcher" is the highest-level object; it handles making sure that
  46. * messages are received and delivered properly. Only the mainloop
  47. * should handle this type directly.
  48. */
  49. typedef struct dispatch_t dispatch_t;
  50. struct dispatch_cfg_t;
  51. dispatch_t *dispatch_new(const struct dispatch_cfg_t *cfg);
  52. /**
  53. * Free a dispatcher. Tor does this at exit.
  54. */
  55. #define dispatch_free(d) \
  56. FREE_AND_NULL(dispatch_t, dispatch_free_, (d))
  57. void dispatch_free_(dispatch_t *);
  58. int dispatch_send(dispatch_t *d,
  59. subsys_id_t sender,
  60. channel_id_t channel,
  61. message_id_t msg,
  62. msg_type_id_t type,
  63. msg_aux_data_t auxdata);
  64. int dispatch_send_msg(dispatch_t *d, msg_t *m);
  65. int dispatch_send_msg_unchecked(dispatch_t *d, msg_t *m);
  66. /* Flush up to <b>max_msgs</b> currently pending messages from the
  67. * dispatcher. Messages that are not pending when this function are
  68. * called, are not flushed by this call. Return 0 on success, -1 on
  69. * unrecoverable error.
  70. */
  71. int dispatch_flush(dispatch_t *, channel_id_t chan, int max_msgs);
  72. /**
  73. * Function callback type used to alert some other module when a channel's
  74. * queue changes from empty to nonempty.
  75. *
  76. * Ex 1: To cause messages to be processed immediately on-stack, this callback
  77. * should invoke dispatch_flush() directly.
  78. *
  79. * Ex 2: To cause messages to be processed very soon, from the event queue,
  80. * this callback should schedule an event callback to run dispatch_flush().
  81. *
  82. * Ex 3: To cause messages to be processed periodically, this function should
  83. * do nothing, and a periodic event should invoke dispatch_flush().
  84. **/
  85. typedef void (*dispatch_alertfn_t)(struct dispatch_t *,
  86. channel_id_t, void *);
  87. int dispatch_set_alert_fn(dispatch_t *d, channel_id_t chan,
  88. dispatch_alertfn_t fn, void *userdata);
  89. #define dispatch_free_msg(d,msg) \
  90. STMT_BEGIN { \
  91. msg_t **msg_tmp_ptr__ = &(msg); \
  92. dispatch_free_msg_((d), *msg_tmp_ptr__); \
  93. *msg_tmp_ptr__= NULL; \
  94. } STMT_END
  95. void dispatch_free_msg_(const dispatch_t *d, msg_t *msg);
  96. char *dispatch_fmt_msg_data(const dispatch_t *d, const msg_t *msg);
  97. #endif