tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

dispatch.h (4434B)


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