diff options
Diffstat (limited to 'src/include/gnunet_mq_lib.h')
-rw-r--r-- | src/include/gnunet_mq_lib.h | 235 |
1 files changed, 157 insertions, 78 deletions
diff --git a/src/include/gnunet_mq_lib.h b/src/include/gnunet_mq_lib.h index 971c87b18..38ebf6b17 100644 --- a/src/include/gnunet_mq_lib.h +++ b/src/include/gnunet_mq_lib.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2012-2013 GNUnet e.V. | 3 | Copyright (C) 2012-2016 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @author Florian Dold | 22 | * @author Florian Dold |
23 | * @author Christian Grothoff | ||
23 | * | 24 | * |
24 | * @file | 25 | * @file |
25 | * General-purpose message queue | 26 | * General-purpose message queue |
@@ -117,7 +118,7 @@ GNUNET_MQ_extract_nested_mh_ (const struct GNUNET_MessageHeader *mh, | |||
117 | 118 | ||
118 | 119 | ||
119 | /** | 120 | /** |
120 | * Implementation of the GNUNET_MQ_msg_nested_mh macro. | 121 | * Implementation of the #GNUNET_MQ_msg_nested_mh macro. |
121 | * | 122 | * |
122 | * @param mhp pointer to the message header pointer that will be changed to allocate at | 123 | * @param mhp pointer to the message header pointer that will be changed to allocate at |
123 | * the newly allocated space for the message. | 124 | * the newly allocated space for the message. |
@@ -132,13 +133,6 @@ GNUNET_MQ_msg_nested_mh_ (struct GNUNET_MessageHeader **mhp, | |||
132 | const struct GNUNET_MessageHeader *nested_mh); | 133 | const struct GNUNET_MessageHeader *nested_mh); |
133 | 134 | ||
134 | 135 | ||
135 | |||
136 | /** | ||
137 | * End-marker for the handlers array | ||
138 | */ | ||
139 | #define GNUNET_MQ_HANDLERS_END {NULL, 0, 0} | ||
140 | |||
141 | |||
142 | /** | 136 | /** |
143 | * Opaque handle to a message queue. | 137 | * Opaque handle to a message queue. |
144 | */ | 138 | */ |
@@ -156,7 +150,9 @@ struct GNUNET_MQ_Envelope; | |||
156 | enum GNUNET_MQ_Error | 150 | enum GNUNET_MQ_Error |
157 | { | 151 | { |
158 | /** | 152 | /** |
159 | * FIXME: document! | 153 | * Failed to read message from the network. |
154 | * FIXME: Likely not properly distinguished | ||
155 | * from TIMEOUT case in the code! | ||
160 | */ | 156 | */ |
161 | GNUNET_MQ_ERROR_READ = 1, | 157 | GNUNET_MQ_ERROR_READ = 1, |
162 | 158 | ||
@@ -168,7 +164,13 @@ enum GNUNET_MQ_Error | |||
168 | /** | 164 | /** |
169 | * FIXME: document! | 165 | * FIXME: document! |
170 | */ | 166 | */ |
171 | GNUNET_MQ_ERROR_TIMEOUT = 4 | 167 | GNUNET_MQ_ERROR_TIMEOUT = 4, |
168 | |||
169 | /** | ||
170 | * We received a message that was malformed and thus | ||
171 | * could not be passed to its handler. | ||
172 | */ | ||
173 | GNUNET_MQ_ERROR_MALFORMED = 8 | ||
172 | }; | 174 | }; |
173 | 175 | ||
174 | 176 | ||
@@ -184,6 +186,19 @@ typedef void | |||
184 | 186 | ||
185 | 187 | ||
186 | /** | 188 | /** |
189 | * Called when a message needs to be validated. | ||
190 | * | ||
191 | * @param cls closure | ||
192 | * @param msg the received message | ||
193 | * @return #GNUNET_OK if the message is well-formed, | ||
194 | * #GNUNET_SYSERR if not | ||
195 | */ | ||
196 | typedef int | ||
197 | (*GNUNET_MQ_MessageValidationCallback) (void *cls, | ||
198 | const struct GNUNET_MessageHeader *msg); | ||
199 | |||
200 | |||
201 | /** | ||
187 | * Signature of functions implementing the | 202 | * Signature of functions implementing the |
188 | * sending functionality of a message queue. | 203 | * sending functionality of a message queue. |
189 | * | 204 | * |
@@ -251,26 +266,136 @@ typedef void | |||
251 | struct GNUNET_MQ_MessageHandler | 266 | struct GNUNET_MQ_MessageHandler |
252 | { | 267 | { |
253 | /** | 268 | /** |
269 | * Callback to validate a message of the specified @e type. | ||
270 | * The closure given to @e mv will be this struct (not @e ctx). | ||
271 | * Using NULL means only size-validation using | ||
272 | * @e expected_size. In this case, @e expected_size must | ||
273 | * be non-zero. | ||
274 | */ | ||
275 | GNUNET_MQ_MessageValidationCallback mv; | ||
276 | |||
277 | /** | ||
254 | * Callback, called every time a new message of | 278 | * Callback, called every time a new message of |
255 | * the specified type has been receied. | 279 | * the specified @e type has been receied. |
280 | * The closure given to @e mv will be this struct (not @e ctx). | ||
256 | */ | 281 | */ |
257 | GNUNET_MQ_MessageCallback cb; | 282 | GNUNET_MQ_MessageCallback cb; |
258 | 283 | ||
259 | /** | 284 | /** |
260 | * Type of the message this handler covers. | 285 | * Closure for @e mv and @e cb. |
286 | */ | ||
287 | void *cls; | ||
288 | |||
289 | /** | ||
290 | * Type of the message this handler covers, in host byte order. | ||
261 | */ | 291 | */ |
262 | uint16_t type; | 292 | uint16_t type; |
263 | 293 | ||
264 | /** | 294 | /** |
265 | * Expected size of messages of this type. Use 0 for | 295 | * Expected size of messages of this type. Minimum size of the |
266 | * variable-size. If non-zero, messages of the given | 296 | * message if @e mv is non-NULL. Messages of the given type will be |
267 | * type will be discarded (and the connection closed) | 297 | * discarded (and the connection closed with an error reported to |
268 | * if they do not have the right size. | 298 | * the application) if they do not have the right size. |
269 | */ | 299 | */ |
270 | uint16_t expected_size; | 300 | uint16_t expected_size; |
271 | }; | 301 | }; |
272 | 302 | ||
273 | 303 | ||
304 | /** | ||
305 | * End-marker for the handlers array | ||
306 | */ | ||
307 | #define GNUNET_MQ_handler_end() {NULL, NULL, NULL, 0, 0} | ||
308 | |||
309 | |||
310 | /** | ||
311 | * Defines a static function @a name which takes as a single argument | ||
312 | * a message handler for fixed-sized messages of type @a code and with | ||
313 | * a message type argument of @a str. Given such an argument, the | ||
314 | * function @name will return a `struct GNUNET_MQ_MessageHandler` | ||
315 | * for the given message type. | ||
316 | * | ||
317 | * The macro is to be used as follows: | ||
318 | * <code> | ||
319 | * struct GNUNET_MessageTest { ... }; // must be fixed size | ||
320 | * GNUNET_MQ_hd_fixed_size(test_message, | ||
321 | * GNUNET_MESSAGE_TYPE_TEST, | ||
322 | * struct GNUNET_MessageTest); | ||
323 | * static void | ||
324 | * handle_test_message (void *cls, // the struct GNUNET_MQ_MessageHandler | ||
325 | * const struct GNUNET_MessageTest *msg) | ||
326 | * { ... } | ||
327 | * | ||
328 | * struct GNUNET_MQ_MessageHandler handlers[] = { | ||
329 | * make_test_message_handler (), | ||
330 | * GNUNET_MQ_handler_end() | ||
331 | * }; | ||
332 | * | ||
333 | * @param name unique basename for the functions | ||
334 | * @param code message type constant | ||
335 | * @param str type of the message (a struct) | ||
336 | */ | ||
337 | #define GNUNET_MQ_hd_fixed_size(name,code,str) \ | ||
338 | struct GNUNET_MQ_MessageHandler \ | ||
339 | make_##name##_handler (void *cls) { \ | ||
340 | void (*cb)(void *cls, const str *msg) = &handle_##name; \ | ||
341 | struct GNUNET_MQ_MessageHandler mh = { \ | ||
342 | NULL, (GNUNET_MQ_MessageCallback) cb, \ | ||
343 | cls, code, sizeof (str) }; \ | ||
344 | return mh; \ | ||
345 | } | ||
346 | |||
347 | |||
348 | /** | ||
349 | * Defines a static function @a name which takes two arguments and a | ||
350 | * context-pointer for validating and handling variable-sized messages | ||
351 | * of type @a code and with a message type argument of @a str. Given | ||
352 | * such arguments, the function @name will return a `struct | ||
353 | * GNUNET_MQ_MessageHandler` for the given message type. | ||
354 | * | ||
355 | * The macro is to be used as follows: | ||
356 | * <code> | ||
357 | * struct GNUNET_MessageTest { ... }; // can be variable size | ||
358 | * GNUNET_MQ_hd_var_size(test_message, | ||
359 | * GNUNET_MESSAGE_TYPE_TEST, | ||
360 | * struct GNUNET_MessageTest); | ||
361 | * static int | ||
362 | * check_test (void *cls, | ||
363 | * const struct GNUNET_MessageTest *msg) | ||
364 | * { | ||
365 | * const char *ctx = cls; | ||
366 | * GNUNET_assert (0 == strcmp ("context", ctx)); | ||
367 | * // ... | ||
368 | * } | ||
369 | * static void | ||
370 | * handle_test (void *cls, | ||
371 | * const struct GNUNET_MessageTest *msg) | ||
372 | * { | ||
373 | * const char *ctx = cls; | ||
374 | * GNUNET_assert (0 == strcmp ("context", ctx)); | ||
375 | * // ... | ||
376 | * } | ||
377 | * | ||
378 | * struct GNUNET_MQ_MessageHandler handlers[] = { | ||
379 | * make_test_message_handler ("context"), | ||
380 | * GNUNET_MQ_handler_end() | ||
381 | * }; | ||
382 | * | ||
383 | * @param name unique basename for the functions | ||
384 | * @param code message type constant | ||
385 | * @param str type of the message (a struct) | ||
386 | */ | ||
387 | #define GNUNET_MQ_hd_var_size(name,code,str) \ | ||
388 | struct GNUNET_MQ_MessageHandler \ | ||
389 | make_##name##_handler (void *ctx) { \ | ||
390 | int (*mv)(void *cls, const str *msg) = &check_##name; \ | ||
391 | void (*cb)(void *cls, const str *msg) = &handle_##name;\ | ||
392 | struct GNUNET_MQ_MessageHandler mh = \ | ||
393 | { (GNUNET_MQ_MessageValidationCallback) mv, \ | ||
394 | (GNUNET_MQ_MessageCallback) cb, \ | ||
395 | ctx, code, sizeof (str) }; \ | ||
396 | return mh; \ | ||
397 | } | ||
398 | |||
274 | 399 | ||
275 | /** | 400 | /** |
276 | * Create a new envelope. | 401 | * Create a new envelope. |
@@ -321,17 +446,18 @@ GNUNET_MQ_send_cancel (struct GNUNET_MQ_Envelope *ev); | |||
321 | 446 | ||
322 | 447 | ||
323 | /** | 448 | /** |
324 | * Associate the assoc_data in mq with a unique request id. | 449 | * Associate the assoc_data in @a mq with a unique request id. |
325 | * | 450 | * |
326 | * @param mq message queue, id will be unique for the queue | 451 | * @param mq message queue, id will be unique for the queue |
327 | * @param assoc_data to associate | 452 | * @param assoc_data to associate |
328 | */ | 453 | */ |
329 | uint32_t | 454 | uint32_t |
330 | GNUNET_MQ_assoc_add (struct GNUNET_MQ_Handle *mq, void *assoc_data); | 455 | GNUNET_MQ_assoc_add (struct GNUNET_MQ_Handle *mq, |
456 | void *assoc_data); | ||
331 | 457 | ||
332 | 458 | ||
333 | /** | 459 | /** |
334 | * Get the data associated with a request id in a queue | 460 | * Get the data associated with a @a request_id in a queue |
335 | * | 461 | * |
336 | * @param mq the message queue with the association | 462 | * @param mq the message queue with the association |
337 | * @param request_id the request id we are interested in | 463 | * @param request_id the request id we are interested in |
@@ -343,7 +469,7 @@ GNUNET_MQ_assoc_get (struct GNUNET_MQ_Handle *mq, | |||
343 | 469 | ||
344 | 470 | ||
345 | /** | 471 | /** |
346 | * Remove the association for a request id | 472 | * Remove the association for a @a request_id |
347 | * | 473 | * |
348 | * @param mq the message queue with the association | 474 | * @param mq the message queue with the association |
349 | * @param request_id the request id we want to remove | 475 | * @param request_id the request id we want to remove |
@@ -355,33 +481,6 @@ GNUNET_MQ_assoc_remove (struct GNUNET_MQ_Handle *mq, | |||
355 | 481 | ||
356 | 482 | ||
357 | /** | 483 | /** |
358 | * Create a message queue for a GNUNET_CLIENT_Connection. | ||
359 | * If handlers are specfied, receive messages from the connection. | ||
360 | * | ||
361 | * @param connection the client connection | ||
362 | * @param handlers handlers for receiving messages | ||
363 | * @param error_handler error handler | ||
364 | * @param cls closure for the handlers | ||
365 | * @return the message queue | ||
366 | */ | ||
367 | struct GNUNET_MQ_Handle * | ||
368 | GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection, | ||
369 | const struct GNUNET_MQ_MessageHandler *handlers, | ||
370 | GNUNET_MQ_ErrorHandler error_handler, | ||
371 | void *cls); | ||
372 | |||
373 | |||
374 | /** | ||
375 | * Create a message queue for a GNUNET_SERVER_Client. | ||
376 | * | ||
377 | * @param client the client | ||
378 | * @return the message queue | ||
379 | */ | ||
380 | struct GNUNET_MQ_Handle * | ||
381 | GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client); | ||
382 | |||
383 | |||
384 | /** | ||
385 | * Create a message queue for the specified handlers. | 484 | * Create a message queue for the specified handlers. |
386 | * | 485 | * |
387 | * @param send function the implements sending messages | 486 | * @param send function the implements sending messages |
@@ -404,24 +503,6 @@ GNUNET_MQ_queue_for_callbacks (GNUNET_MQ_SendImpl send, | |||
404 | 503 | ||
405 | 504 | ||
406 | /** | 505 | /** |
407 | * Replace the handlers of a message queue with new handlers. Takes | ||
408 | * effect immediately, even for messages that already have been | ||
409 | * received, but for with the handler has not been called. | ||
410 | * | ||
411 | * If the message queue does not support receiving messages, | ||
412 | * this function has no effect. | ||
413 | * | ||
414 | * @param mq message queue | ||
415 | * @param new_handlers new handlers | ||
416 | * @param cls new closure for the handlers | ||
417 | */ | ||
418 | void | ||
419 | GNUNET_MQ_replace_handlers (struct GNUNET_MQ_Handle *mq, | ||
420 | const struct GNUNET_MQ_MessageHandler *new_handlers, | ||
421 | void *cls); | ||
422 | |||
423 | |||
424 | /** | ||
425 | * Call a callback once the envelope has been sent, that is, | 506 | * Call a callback once the envelope has been sent, that is, |
426 | * sending it can not be canceled anymore. | 507 | * sending it can not be canceled anymore. |
427 | * There can be only one notify sent callback per envelope. | 508 | * There can be only one notify sent callback per envelope. |
@@ -476,10 +557,9 @@ GNUNET_MQ_inject_error (struct GNUNET_MQ_Handle *mq, | |||
476 | 557 | ||
477 | 558 | ||
478 | /** | 559 | /** |
479 | * Call the send implementation for the next queued message, | 560 | * Call the send implementation for the next queued message, if any. |
480 | * if any. | 561 | * Only useful for implementing message queues, results in undefined |
481 | * Only useful for implementing message queues, | 562 | * behavior if not used carefully. |
482 | * results in undefined behavior if not used carefully. | ||
483 | * | 563 | * |
484 | * @param mq message queue to send the next message with | 564 | * @param mq message queue to send the next message with |
485 | */ | 565 | */ |
@@ -488,15 +568,14 @@ GNUNET_MQ_impl_send_continue (struct GNUNET_MQ_Handle *mq); | |||
488 | 568 | ||
489 | 569 | ||
490 | /** | 570 | /** |
491 | * Get the message that should currently be sent. | 571 | * Get the message that should currently be sent. The returned |
492 | * The returned message is only valid until #GNUNET_MQ_impl_send_continue | 572 | * message is only valid until #GNUNET_MQ_impl_send_continue is |
493 | * is called. | 573 | * called. Fails if there is no current message. Only useful for |
494 | * Fails if there is no current message. | 574 | * implementing message queues, results in undefined behavior if not |
495 | * Only useful for implementing message queues, | 575 | * used carefully. |
496 | * results in undefined behavior if not used carefully. | ||
497 | * | 576 | * |
498 | * @param mq message queue with the current message, only valid | 577 | * @param mq message queue with the current message, only valid |
499 | * until #GNUNET_MQ_impl_send_continue is called | 578 | * until #GNUNET_MQ_impl_send_continue() is called |
500 | * @return message to send, never NULL | 579 | * @return message to send, never NULL |
501 | */ | 580 | */ |
502 | const struct GNUNET_MessageHeader * | 581 | const struct GNUNET_MessageHeader * |
@@ -511,7 +590,7 @@ GNUNET_MQ_impl_current (struct GNUNET_MQ_Handle *mq); | |||
511 | * implementation state, continuations that are scheduled | 590 | * implementation state, continuations that are scheduled |
512 | * by the implementation function often only have one closure | 591 | * by the implementation function often only have one closure |
513 | * argument, with this function it is possible to get at the | 592 | * argument, with this function it is possible to get at the |
514 | * implementation state when only passing the GNUNET_MQ_Handle | 593 | * implementation state when only passing the `struct GNUNET_MQ_Handle` |
515 | * as closure. | 594 | * as closure. |
516 | * | 595 | * |
517 | * @param mq message queue with the current message | 596 | * @param mq message queue with the current message |