Tor 0.4.9.0-alpha-dev
mainloop_pubsub.c
Go to the documentation of this file.
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/**
8 * @file mainloop_pubsub.c
9 * @brief Connect the publish-subscribe code to the main-loop.
10 *
11 * This module is responsible for instantiating all the channels used by the
12 * publish-subscribe code, and making sure that each one's messages are
13 * processed when appropriate.
14 **/
15
16#include "orconfig.h"
17
18#include "core/or/or.h"
21
26#include "lib/pubsub/pubsub.h"
28
29/**
30 * Dispatcher to use for delivering messages.
31 **/
33static pubsub_items_t *the_pubsub_items = NULL;
34/**
35 * A list of mainloop_event_t, indexed by channel ID, to flush the messages
36 * on a channel.
37 **/
39
40/**
41 * Mainloop event callback: flush all the messages in a channel.
42 *
43 * The channel is encoded as a pointer, and passed via arg.
44 **/
45static void
47{
48 (void)ev;
49 if (!the_dispatcher)
50 return;
51
52 channel_id_t chan = (channel_id_t)(uintptr_t)(arg);
53 dispatch_flush(the_dispatcher, chan, INT_MAX);
54}
55
56/**
57 * Construct our global pubsub object from <b>builder</b>. Return 0 on
58 * success, -1 on failure. */
59int
61{
62 int rv = -1;
64
65 the_dispatcher = pubsub_builder_finalize(builder, &the_pubsub_items);
66 if (! the_dispatcher)
67 goto err;
68
69 rv = 0;
70 goto done;
71 err:
73 done:
74 return rv;
75}
76
77/**
78 * Install libevent events for all of the pubsub channels.
79 *
80 * Invoke this after tor_mainloop_connect_pubsub, and after libevent has been
81 * initialized.
82 */
83void
85{
88
89 const size_t num_channels = get_num_channel_ids();
91 for (size_t i = 0; i < num_channels; ++i) {
94 (void*)(uintptr_t)(i)));
95 }
96}
97
98/**
99 * Dispatch alertfn callback: do nothing. Implements DELIV_NEVER.
100 **/
101static void
102alertfn_never(dispatch_t *d, channel_id_t chan, void *arg)
103{
104 (void)d;
105 (void)chan;
106 (void)arg;
107}
108
109/**
110 * Dispatch alertfn callback: activate a mainloop event. Implements
111 * DELIV_PROMPT.
112 **/
113static void
114alertfn_prompt(dispatch_t *d, channel_id_t chan, void *arg)
115{
116 (void)d;
117 (void)chan;
118 mainloop_event_t *event = arg;
120}
121
122/**
123 * Dispatch alertfn callback: flush all messages right now. Implements
124 * DELIV_IMMEDIATE.
125 **/
126static void
127alertfn_immediate(dispatch_t *d, channel_id_t chan, void *arg)
128{
129 (void) arg;
130 dispatch_flush(d, chan, INT_MAX);
131}
132
133/**
134 * Set the strategy to be used for delivering messages on the named channel.
135 *
136 * This function needs to be called once globally for each channel, to
137 * set up how messages are delivered.
138 **/
139int
140tor_mainloop_set_delivery_strategy(const char *msg_channel_name,
141 deliv_strategy_t strategy)
142{
143 channel_id_t chan = get_channel_id(msg_channel_name);
144 if (BUG(chan == ERROR_ID) ||
145 BUG(chan >= smartlist_len(alert_events)))
146 return -1;
147
148 switch (strategy) {
149 case DELIV_NEVER:
151 break;
152 case DELIV_PROMPT:
154 smartlist_get(alert_events, chan));
155 break;
156 case DELIV_IMMEDIATE:
158 break;
159 }
160 return 0;
161}
162
163/**
164 * Remove all pubsub dispatchers and events from the mainloop.
165 **/
166void
168{
169 if (the_pubsub_items) {
170 pubsub_items_clear_bindings(the_pubsub_items);
171 pubsub_items_free(the_pubsub_items);
172 }
173 if (alert_events) {
175 mainloop_event_free(ev));
176 smartlist_free(alert_events);
177 }
179}
mainloop_event_t * mainloop_event_postloop_new(void(*cb)(mainloop_event_t *, void *), void *userdata)
void mainloop_event_activate(mainloop_event_t *event)
Header for compat_libevent.c.
Low-level APIs for message-passing system.
int dispatch_set_alert_fn(dispatch_t *d, channel_id_t chan, dispatch_alertfn_t fn, void *userdata)
Definition: dispatch_core.c:88
#define dispatch_free(d)
Definition: dispatch.h:62
int dispatch_flush(dispatch_t *, channel_id_t chan, int max_msgs)
struct dispatch_t dispatch_t
Definition: dispatch.h:53
Header for dispatch_naming.c.
size_t get_num_channel_ids(void)
channel_id_t get_channel_id(const char *)
Header file for mainloop.c.
static dispatch_t * the_dispatcher
static void flush_channel_event(mainloop_event_t *ev, void *arg)
int tor_mainloop_connect_pubsub(struct pubsub_builder_t *builder)
static void alertfn_immediate(dispatch_t *d, channel_id_t chan, void *arg)
static void alertfn_prompt(dispatch_t *d, channel_id_t chan, void *arg)
static void alertfn_never(dispatch_t *d, channel_id_t chan, void *arg)
void tor_mainloop_connect_pubsub_events(void)
void tor_mainloop_disconnect_pubsub(void)
static smartlist_t * alert_events
int tor_mainloop_set_delivery_strategy(const char *msg_channel_name, deliv_strategy_t strategy)
Header for mainloop_pubsub.c.
deliv_strategy_t
@ DELIV_PROMPT
@ DELIV_IMMEDIATE
@ DELIV_NEVER
#define ERROR_ID
Definition: msgtypes.h:34
Master header file for Tor-specific functionality.
Header for OO publish-subscribe functionality.
dispatch_t * pubsub_builder_finalize(pubsub_builder_t *builder, pubsub_items_t **items_out)
Definition: pubsub_build.c:278
void pubsub_items_clear_bindings(pubsub_items_t *items)
Definition: pubsub_build.c:263
Header used for constructing the OO publish-subscribe facility.
struct pubsub_items_t pubsub_items_t
Definition: pubsub_build.h:35
struct pubsub_builder_t pubsub_builder_t
Definition: pubsub_build.h:28
#define pubsub_items_free(cfg)
Definition: pubsub_build.h:93
Header for smartlist.c.
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
#define tor_assert(expr)
Definition: util_bug.h:103