tor  0.4.2.1-alpha-dev
mainloop_pubsub.c
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 
7 #include "orconfig.h"
8 
9 #include "core/or/or.h"
10 #include "core/mainloop/mainloop.h"
11 #include "core/mainloop/mainloop_pubsub.h"
12 
14 #include "lib/dispatch/dispatch.h"
15 #include "lib/dispatch/dispatch_naming.h"
17 #include "lib/pubsub/pubsub.h"
19 
23 static dispatch_t *the_dispatcher = NULL;
24 static pubsub_items_t *the_pubsub_items = NULL;
29 static smartlist_t *alert_events = NULL;
30 
36 static void
37 flush_channel_event(mainloop_event_t *ev, void *arg)
38 {
39  (void)ev;
40  if (!the_dispatcher)
41  return;
42 
43  channel_id_t chan = (channel_id_t)(uintptr_t)(arg);
44  dispatch_flush(the_dispatcher, chan, INT_MAX);
45 }
46 
50 int
51 tor_mainloop_connect_pubsub(struct pubsub_builder_t *builder)
52 {
53  int rv = -1;
54  tor_mainloop_disconnect_pubsub();
55 
56  the_dispatcher = pubsub_builder_finalize(builder, &the_pubsub_items);
57  if (! the_dispatcher)
58  goto err;
59 
60  rv = 0;
61  goto done;
62  err:
63  tor_mainloop_disconnect_pubsub();
64  done:
65  return rv;
66 }
67 
74 void
75 tor_mainloop_connect_pubsub_events(void)
76 {
77  tor_assert(the_dispatcher);
78  tor_assert(! alert_events);
79 
80  const size_t num_channels = get_num_channel_ids();
81  alert_events = smartlist_new();
82  for (size_t i = 0; i < num_channels; ++i) {
83  smartlist_add(alert_events,
84  mainloop_event_postloop_new(flush_channel_event,
85  (void*)(uintptr_t)(i)));
86  }
87 }
88 
92 static void
93 alertfn_never(dispatch_t *d, channel_id_t chan, void *arg)
94 {
95  (void)d;
96  (void)chan;
97  (void)arg;
98 }
99 
104 static void
105 alertfn_prompt(dispatch_t *d, channel_id_t chan, void *arg)
106 {
107  (void)d;
108  (void)chan;
109  mainloop_event_t *event = arg;
111 }
112 
117 static void
118 alertfn_immediate(dispatch_t *d, channel_id_t chan, void *arg)
119 {
120  (void) arg;
121  dispatch_flush(d, chan, INT_MAX);
122 }
123 
130 int
131 tor_mainloop_set_delivery_strategy(const char *msg_channel_name,
132  deliv_strategy_t strategy)
133 {
134  channel_id_t chan = get_channel_id(msg_channel_name);
135  if (BUG(chan == ERROR_ID) ||
136  BUG(chan >= smartlist_len(alert_events)))
137  return -1;
138 
139  switch (strategy) {
140  case DELIV_NEVER:
141  dispatch_set_alert_fn(the_dispatcher, chan, alertfn_never, NULL);
142  break;
143  case DELIV_PROMPT:
144  dispatch_set_alert_fn(the_dispatcher, chan, alertfn_prompt,
145  smartlist_get(alert_events, chan));
146  break;
147  case DELIV_IMMEDIATE:
148  dispatch_set_alert_fn(the_dispatcher, chan, alertfn_immediate, NULL);
149  break;
150  }
151  return 0;
152 }
153 
157 void
158 tor_mainloop_disconnect_pubsub(void)
159 {
160  if (the_pubsub_items) {
161  pubsub_items_clear_bindings(the_pubsub_items);
162  pubsub_items_free(the_pubsub_items);
163  }
164  if (alert_events) {
165  SMARTLIST_FOREACH(alert_events, mainloop_event_t *, ev,
166  mainloop_event_free(ev));
167  smartlist_free(alert_events);
168  }
169  dispatch_free(the_dispatcher);
170 }
Header for smartlist.c.
#define ERROR_ID
Definition: msgtypes.h:34
struct pubsub_builder_t pubsub_builder_t
Definition: pubsub_build.h:28
struct pubsub_items_t pubsub_items_t
Definition: pubsub_build.h:35
void smartlist_add(smartlist_t *sl, void *element)
mainloop_event_t * mainloop_event_postloop_new(void(*cb)(mainloop_event_t *, void *), void *userdata)
Header file for mainloop.c.
void mainloop_event_activate(mainloop_event_t *event)
struct dispatch_t dispatch_t
Definition: dispatch.h:53
void pubsub_items_clear_bindings(pubsub_items_t *items)
Definition: pubsub_build.c:263
tor_assert(buffer)
Low-level APIs for message-passing system.
int dispatch_flush(dispatch_t *, channel_id_t chan, int max_msgs)
Master header file for Tor-specific functionality.
dispatch_t * pubsub_builder_finalize(pubsub_builder_t *builder, pubsub_items_t **items_out)
Definition: pubsub_build.c:278
int dispatch_set_alert_fn(dispatch_t *d, channel_id_t chan, dispatch_alertfn_t fn, void *userdata)
Definition: dispatch_core.c:88
#define SMARTLIST_FOREACH(sl, type, var, cmd)
Header for OO publish-subscribe functionality.
#define dispatch_free(d)
Definition: dispatch.h:62
Header for compat_libevent.c.
Header used for constructing the OO publish-subscribe facility.