tor  0.4.2.1-alpha-dev
pubsub_macros.h
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-2018, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
128 #ifndef TOR_DISPATCH_MSG_H
129 #define TOR_DISPATCH_MSG_H
130 
131 #include "lib/cc/compat_compiler.h"
132 #include "lib/dispatch/dispatch_naming.h"
135 #include "lib/pubsub/pubsub_flags.h"
136 #include "lib/pubsub/pubsub_publish.h"
137 
138 /* Implemenation notes:
139  *
140  * For a messagename "foo", the DECLARE_MESSAGE*() macros must declare:
141  *
142  * msg_arg_type__foo -- a typedef for the argument type of the foo message.
143  * msg_arg_consttype__foo -- a typedef for the const argument type of the
144  * foo message.
145  * msg_arg_name__foo[] -- a static string constant holding the unique
146  * identifier for the type of the foo message.
147  * msg_arg_get__foo() -- an inline function taking a msg_aux_data_t and
148  * returning the C data type.
149  * msg_arg_set__foo() -- an inline function taking a msg_aux_data_t and
150  * the C type, setting the msg_aux_data_t to hold the C type.
151  *
152  * For a messagename "foo", the DECLARE_PUBLISH() macro must declare:
153  *
154  * pub_binding__foo -- A static pub_binding_t object used to send messages
155  * from this module.
156  * publish_fn__foo -- A function taking an argument of the appropriate
157  * C type, to be invoked by PUBLISH().
158  *
159  * For a messagename "foo", the DECLARE_SUBSCRIBE() macro must declare:
160  *
161  * hookfn -- A user-provided function name, with the correct signature.
162  * recv_fn__foo -- A wrapper callback that takes a msg_t *, and calls
163  * hookfn with the appropriate arguments.
164  */
165 
166 /* Macro to declare common elements shared by DECLARE_MESSAGE and
167  * DECLARE_MESSAGE_INT. Don't call this directly.
168  *
169  * Note that the "msg_arg_name" string constant is defined in each
170  * translation unit. This might be undesirable; we can tweak it in the
171  * future if need be.
172  */
173 #define DECLARE_MESSAGE_COMMON__(messagename, typename, c_type) \
174  typedef c_type msg_arg_type__ ##messagename; \
175  typedef const c_type msg_arg_consttype__ ##messagename; \
176  ATTR_UNUSED static const char msg_arg_name__ ##messagename[] = # typename;
177 
192 #define DECLARE_MESSAGE(messagename, typename, c_ptr_type) \
193  DECLARE_MESSAGE_COMMON__(messagename, typename, c_ptr_type) \
194  ATTR_UNUSED static inline c_ptr_type \
195  msg_arg_get__ ##messagename(msg_aux_data_t m) \
196  { \
197  return m.ptr; \
198  } \
199  ATTR_UNUSED static inline void \
200  msg_arg_set__ ##messagename(msg_aux_data_t *m, c_ptr_type v) \
201  { \
202  m->ptr = v; \
203  } \
204  EAT_SEMICOLON
205 
219 #define DECLARE_MESSAGE_INT(messagename, typename, c_type) \
220  DECLARE_MESSAGE_COMMON__(messagename, typename, c_type) \
221  ATTR_UNUSED static inline c_type \
222  msg_arg_get__ ##messagename(msg_aux_data_t m) \
223  { \
224  return (c_type)m.u64; \
225  } \
226  ATTR_UNUSED static inline void \
227  msg_arg_set__ ##messagename(msg_aux_data_t *m, c_type v) \
228  { \
229  m->u64 = (uint64_t)v; \
230  } \
231  EAT_SEMICOLON
232 
245 #define DECLARE_PUBLISH(messagename) \
246  static pub_binding_t pub_binding__ ##messagename; \
247  static void \
248  publish_fn__ ##messagename(msg_arg_type__ ##messagename arg) \
249  { \
250  msg_aux_data_t data; \
251  msg_arg_set__ ##messagename(&data, arg); \
252  pubsub_pub_(&pub_binding__ ##messagename, data); \
253  } \
254  EAT_SEMICOLON
255 
272 #define DECLARE_SUBSCRIBE(messagename, hookfn) \
273  static void hookfn(const msg_t *, \
274  const msg_arg_consttype__ ##messagename); \
275  static void recv_fn__ ## messagename(const msg_t *m) \
276  { \
277  msg_arg_type__ ## messagename arg; \
278  arg = msg_arg_get__ ##messagename(m->aux_data__); \
279  hookfn(m, arg); \
280  } \
281  EAT_SEMICOLON
282 
287 #define DISPATCH__FAKE_USE_OF_PUBFN_(messagename) \
288  ( 0 ? (publish_fn__ ##messagename((msg_arg_type__##messagename)0), 1) \
289  : 1)
290 
291 /*
292  * This macro is for internal use. It backs DISPATCH_ADD_PUB*()
293  */
294 #define DISPATCH_ADD_PUB_(connector, channel, messagename, flags) \
295  ( \
296  DISPATCH__FAKE_USE_OF_PUBFN_(messagename), \
297  pubsub_add_pub_((connector), \
298  &pub_binding__ ##messagename, \
299  get_channel_id(# channel), \
300  get_message_id(# messagename), \
301  get_msg_type_id(msg_arg_name__ ## messagename), \
302  (flags), \
303  __FILE__, \
304  __LINE__) \
305  )
306 
313 #define DISPATCH_ADD_PUB(connector, channel, messagename) \
314  DISPATCH_ADD_PUB_(connector, channel, messagename, 0)
315 
322 #define DISPATCH_ADD_PUB_EXCL(connector, channel, messagename) \
323  DISPATCH_ADD_PUB_(connector, channel, messagename, DISP_FLAG_EXCL)
324 
325 /*
326  * This macro is for internal use. It backs DISPATCH_ADD_SUB*()
327  */
328 #define DISPATCH_ADD_SUB_(connector, channel, messagename, flags) \
329  pubsub_add_sub_((connector), \
330  recv_fn__ ##messagename, \
331  get_channel_id(#channel), \
332  get_message_id(# messagename), \
333  get_msg_type_id(msg_arg_name__ ##messagename), \
334  (flags), \
335  __FILE__, \
336  __LINE__)
337 /*
338  * Use a given connector and channel name to declare that this subsystem will
339  * receive a given message type.
340  *
341  * Call this macro from within the add_subscriptions() function of a module.
342  */
343 #define DISPATCH_ADD_SUB(connector, channel, messagename) \
344  DISPATCH_ADD_SUB_(connector, channel, messagename, 0)
345 
352 #define DISPATCH_ADD_SUB_EXCL(connector, channel, messagename) \
353  DISPATCH_ADD_SUB_(connector, channel, messagename, DISP_FLAG_EXCL)
354 
359 #define PUBLISH(messagename, arg) \
360  publish_fn__ ##messagename(arg)
361 
366 #define DISPATCH_REGISTER_TYPE(con, type, fns) \
367  pubsub_connector_register_type_((con), \
368  get_msg_type_id(#type), \
369  (fns), \
370  __FILE__, \
371  __LINE__)
372 
373 #endif /* !defined(TOR_DISPATCH_MSG_H) */
Flags that can be set on publish/subscribe messages.
Declaration of pub_binding_t.
Utility macros to handle different features and behavior in different compilers.
Header for functions that add relationships to a pubsub builder.