13 #define PUBSUB_PRIVATE
31 const pubsub_cfg_t *item);
37 static pubsub_adjmap_t *
40 pubsub_adjmap_t *map = tor_malloc_zero(
sizeof(*map));
41 const size_t n_subsystems = get_num_subsys_ids();
42 const size_t n_msgs = get_num_message_ids();
44 map->n_subsystems = n_subsystems;
47 map->pub_by_subsys = tor_calloc(n_subsystems,
sizeof(
smartlist_t*));
48 map->sub_by_subsys = tor_calloc(n_subsystems,
sizeof(
smartlist_t*));
49 map->pub_by_msg = tor_calloc(n_msgs,
sizeof(
smartlist_t*));
50 map->sub_by_msg = tor_calloc(n_msgs,
sizeof(
smartlist_t*));
54 } SMARTLIST_FOREACH_END(item);
64 const pubsub_cfg_t *item)
72 if (item->is_publish) {
73 by_subsys = &map->pub_by_subsys[item->subsys];
74 by_msg = &map->pub_by_msg[item->msg];
76 by_subsys = &map->sub_by_subsys[item->subsys];
77 by_msg = &map->sub_by_msg[item->msg];
91 #define pubsub_adjmap_free(m) \
92 FREE_AND_NULL(pubsub_adjmap_t, pubsub_adjmap_free_, m)
104 for (
unsigned i = 0; i < n; ++i) {
105 smartlist_free(lsts[i]);
132 return smartlist_len(sl);
145 strlcat(buf,
" EXCL",
sizeof(buf));
148 strlcat(buf,
" STUB",
sizeof(buf));
150 return buf[0] ? buf+1 : buf;
163 "%s%s %s: %s{%s} on %s (%s) <%u %u %u %u %x> [%s:%d]",
165 get_subsys_id_name(cfg->subsys),
166 cfg->is_publish ?
"PUB" :
"SUB",
167 get_message_id_name(cfg->msg),
168 get_msg_type_id_name(cfg->type),
171 cfg->subsys, cfg->msg, cfg->type, cfg->channel, cfg->flags,
172 cfg->added_by_file, cfg->added_by_line);
190 } SMARTLIST_FOREACH_END(cfg);
219 for (
unsigned i = 0; i < map->n_subsystems; ++i) {
223 "Message \"%s\" is published and subscribed by the same "
225 get_message_id_name(msg),
226 get_subsys_id_name(i));
231 bitarray_free(published_by);
232 bitarray_free(subscribed_by);
256 const pubsub_cfg_t *item0 = smartlist_get(all, 0);
259 bool pub_excl =
false, sub_excl =
false, chan_same =
true, type_same =
true;
264 chan_same &= (cfg->channel == item0->channel);
265 type_same &= (cfg->type == item0->type);
270 } SMARTLIST_FOREACH_END(cfg);
276 "Message \"%s\" is associated with multiple inconsistent "
278 get_message_id_name(msg));
283 "Message \"%s\" is associated with multiple inconsistent "
285 get_message_id_name(msg));
294 "Message \"%s\" has multiple publishers, but at least one is "
295 "marked as exclusive.",
296 get_message_id_name(msg));
301 "Message \"%s\" has multiple subscribers, but at least one is "
302 "marked as exclusive.",
303 get_message_id_name(msg));
323 if (BUG(msg >= map->n_msgs))
332 if (n_pub == 0 && n_sub == 0) {
333 log_info(
LD_MESG,
"Nobody is publishing or subscribing to message "
335 get_message_id_name(msg));
344 "Message \"%s\" has subscribers, but no publishers.",
345 get_message_id_name(msg));
347 }
else if (n_sub == 0) {
349 "Message \"%s\" has publishers, but no subscribers.",
350 get_message_id_name(msg));
386 for (
unsigned i = 0; i < map->n_msgs; ++i) {
391 return all_ok ? 0 : -1;
Implements a variable-sized (but non-resizeable) bit-array.
static void bitarray_set(bitarray_t *b, int bit)
static unsigned int bitarray_is_set(bitarray_t *b, int bit)
static bitarray_t * bitarray_init_zero(unsigned int n_bits)
Header for compat_string.c.
Header for dispatch_naming.c.
const char * get_channel_id_name(channel_id_t)
void tor_log(int severity, log_domain_mask_t domain, const char *format,...)
Headers for util_malloc.c.
Types used for messages in the dispatcher code.
Header used for constructing the OO publish-subscribe facility.
struct pubsub_items_t pubsub_items_t
struct pubsub_builder_t pubsub_builder_t
private structures used for configuring dispatchers and messages.
static void pubsub_cfg_dump(const pubsub_cfg_t *cfg, int severity, const char *prefix)
static pubsub_adjmap_t * pubsub_build_adjacency_map(const pubsub_items_t *cfg)
static void pubsub_adjmap_free_helper(smartlist_t **lsts, size_t n)
static int pubsub_adjmap_check(const pubsub_adjmap_t *map)
static int smartlist_len_opt(const smartlist_t *sl)
static void pubsub_adjmap_free_(pubsub_adjmap_t *map)
static int lint_message_graph(const pubsub_adjmap_t *map, message_id_t msg, const smartlist_t *pub, const smartlist_t *sub)
static void get_message_bitarray(const pubsub_adjmap_t *map, const smartlist_t *items, bitarray_t **out)
#define pubsub_adjmap_free(m)
int pubsub_builder_check(pubsub_builder_t *builder)
static void pubsub_adjmap_add(pubsub_adjmap_t *map, const pubsub_cfg_t *item)
static int lint_message(const pubsub_adjmap_t *map, message_id_t msg)
static const char * format_flags(unsigned flags)
static int lint_message_consistency(message_id_t msg, const smartlist_t *pub, const smartlist_t *sub)
Flags that can be set on publish/subscribe messages.
void smartlist_add_all(smartlist_t *s1, const smartlist_t *s2)
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
Macros to manage assertions, fatal and non-fatal.