aboutsummaryrefslogtreecommitdiff
path: root/src/include/gnunet_mq_lib.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/gnunet_mq_lib.h')
-rw-r--r--src/include/gnunet_mq_lib.h478
1 files changed, 478 insertions, 0 deletions
diff --git a/src/include/gnunet_mq_lib.h b/src/include/gnunet_mq_lib.h
new file mode 100644
index 000000000..59b692cf0
--- /dev/null
+++ b/src/include/gnunet_mq_lib.h
@@ -0,0 +1,478 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012 Christian Grothoff (and other contributing authors)
4
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
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @author Florian Dold
23 * @file set/mq.h
24 * @brief general purpose request queue
25 */
26#ifndef GNUNET_MQ_H
27#define GNUNET_MQ_H
28
29#include "gnunet_common.h"
30
31
32/**
33 * Allocate a GNUNET_MQ_Message, with extra space allocated after the space needed
34 * by the message struct.
35 * The allocated message will already have the type and size field set.
36 *
37 * @param mvar variable to store the allocated message in;
38 * must have a header field
39 * @param esize extra space to allocate after the message
40 * @param type type of the message
41 * @return the MQ message
42 */
43#define GNUNET_MQ_msg_extra(mvar, esize, type) GNUNET_MQ_msg_((((void)(mvar)->header), (struct GNUNET_MessageHeader**) &(mvar)), (esize) + sizeof *(mvar), (type))
44
45/**
46 * Allocate a GNUNET_MQ_Message.
47 * The allocated message will already have the type and size field set.
48 *
49 * @param mvar variable to store the allocated message in;
50 * must have a header field
51 * @param type type of the message
52 * @return the MQ message
53 */
54#define GNUNET_MQ_msg(mvar, type) GNUNET_MQ_msg_extra(mvar, 0, type)
55
56/**
57 * Append data to the end of an existing MQ message.
58 * If the operation is successful, mqm is changed to point to the new MQ message,
59 * and GNUNET_OK is returned.
60 * On failure, GNUNET_SYSERR is returned, and the pointer mqm is not changed,
61 * the user of this API must take care of disposing the already allocated message
62 * (either by sending it, or by using GNUNET_MQ_discard)
63 *
64 * @param mqm MQ message to augment with additional data
65 * @param src source buffer for the additional data
66 * @param len length of the additional data
67 * @return GNUNET_SYSERR if nesting the message failed,
68 * GNUNET_OK on success
69 */
70#define GNUNET_MQ_nest(mqm, src, len) GNUNET_MQ_nest_ (&mqm, src, len)
71
72
73/**
74 * Append a message to the end of an existing MQ message.
75 * If the operation is successful, mqm is changed to point to the new MQ message,
76 * and GNUNET_OK is returned.
77 * On failure, GNUNET_SYSERR is returned, and the pointer mqm is not changed,
78 * the user of this API must take care of disposing the already allocated message
79 * (either by sending it, or by using GNUNET_MQ_discard)
80 *
81 * @param mqm MQ message to augment with additional data
82 * @param mh the message to append, must be of type 'struct GNUNET_MessageHeader *'
83 */
84#define GNUNET_MQ_nest_mh(mqm, mh) ((NULL == mh) ? (GNUNET_OK) : GNUNET_MQ_nest((mqm), (mh), ntohs ((mh)->size)))
85
86
87/**
88 * Allocate a GNUNET_MQ_Message, where the message only consists of a header.
89 * The allocated message will already have the type and size field set.
90 *
91 * @param type type of the message
92 */
93#define GNUNET_MQ_msg_header(type) GNUNET_MQ_msg_ (NULL, sizeof (struct GNUNET_MessageHeader), type)
94
95
96/**
97 * Allocate a GNUNET_MQ_Message, where the message only consists of a header and extra space.
98 * The allocated message will already have the type and size field set.
99 *
100 * @param mh pointer that will changed to point at to the allocated message header
101 * @param esize extra space to allocate after the message header
102 * @param type type of the message
103 */
104#define GNUNET_MQ_msg_header_extra(mh, esize, type) GNUNET_MQ_msg_ (&mh, (esize) + sizeof (struct GNUNET_MessageHeader), type)
105
106
107/**
108 * End-marker for the handlers array
109 */
110#define GNUNET_MQ_HANDLERS_END {NULL, 0, 0}
111
112
113struct GNUNET_MQ_MessageQueue;
114
115struct GNUNET_MQ_Message;
116
117enum GNUNET_MQ_Error
118{
119 GNUNET_MQ_ERROR_READ = 1,
120 GNUNET_MQ_ERROR_WRITE = 2,
121 GNUNET_MQ_ERROR_TIMEOUT = 4
122};
123
124
125/**
126 * Called when a message has been received.
127 *
128 * @param cls closure
129 * @param msg the received message
130 */
131typedef void (*GNUNET_MQ_MessageCallback) (void *cls, const struct GNUNET_MessageHeader *msg);
132
133
134/**
135 * Signature of functions implementing the
136 * sending part of a message queue
137 *
138 * @param q the message queue
139 * @param m the message
140 */
141typedef void
142(*GNUNET_MQ_SendImpl) (struct GNUNET_MQ_MessageQueue *q, struct GNUNET_MQ_Message *m);
143
144
145typedef void
146(*GNUNET_MQ_DestroyImpl) (struct GNUNET_MQ_MessageQueue *q);
147
148
149/**
150 * Callback used for notifications
151 *
152 * @param cls closure
153 */
154typedef void (*GNUNET_MQ_NotifyCallback) (void *cls);
155
156
157typedef void (*GNUNET_MQ_ErrorHandler) (void *cls, enum GNUNET_MQ_Error error);
158
159
160struct GNUNET_MQ_Message
161{
162 /**
163 * Messages are stored in a linked list
164 */
165 struct GNUNET_MQ_Message *next;
166
167 /**
168 * Messages are stored in a linked list
169 */
170 struct GNUNET_MQ_Message *prev;
171
172 /**
173 * Actual allocated message header,
174 * usually points to the end of the containing GNUNET_MQ_Message
175 */
176 struct GNUNET_MessageHeader *mh;
177
178 /**
179 * Queue the message is queued in, NULL if message is not queued.
180 */
181 struct GNUNET_MQ_MessageQueue *parent_queue;
182
183 /**
184 * Called after the message was sent irrevokably
185 */
186 GNUNET_MQ_NotifyCallback sent_cb;
187
188 /**
189 * Closure for send_cb
190 */
191 void *sent_cls;
192};
193
194
195/**
196 * Handle to a message queue.
197 */
198struct GNUNET_MQ_MessageQueue
199{
200 /**
201 * Handlers array, or NULL if the queue should not receive messages
202 */
203 const struct GNUNET_MQ_Handler *handlers;
204
205 /**
206 * Closure for the handler callbacks,
207 * as well as for the error handler.
208 */
209 void *handlers_cls;
210
211 /**
212 * Actual implementation of message sending,
213 * called when a message is added
214 */
215 GNUNET_MQ_SendImpl send_impl;
216
217 /**
218 * Implementation-dependent queue destruction function
219 */
220 GNUNET_MQ_DestroyImpl destroy_impl;
221
222 /**
223 * Implementation-specific state
224 */
225 void *impl_state;
226
227 /**
228 * Callback will be called when an error occurs.
229 */
230 GNUNET_MQ_ErrorHandler error_handler;
231
232 /**
233 * Linked list of messages pending to be sent
234 */
235 struct GNUNET_MQ_Message *msg_head;
236
237 /**
238 * Linked list of messages pending to be sent
239 */
240 struct GNUNET_MQ_Message *msg_tail;
241
242 /**
243 * Message that is currently scheduled to be
244 * sent. Not the head of the message queue, as the implementation
245 * needs to know if sending has been already scheduled or not.
246 */
247 struct GNUNET_MQ_Message *current_msg;
248
249 /**
250 * Map of associations, lazily allocated
251 */
252 struct GNUNET_CONTAINER_MultiHashMap32 *assoc_map;
253
254 /**
255 * Next id that should be used for the assoc_map,
256 * initialized lazily to a random value together with
257 * assoc_map
258 */
259 uint32_t assoc_id;
260};
261
262
263/**
264 * Message handler for a specific message type.
265 */
266struct GNUNET_MQ_Handler
267{
268 /**
269 * Callback, called every time a new message of
270 * the specified type has been receied.
271 */
272 GNUNET_MQ_MessageCallback cb;
273
274
275 /**
276 * Type of the message this handler covers.
277 */
278 uint16_t type;
279
280 /**
281 * Expected size of messages of this type. Use 0 for
282 * variable-size. If non-zero, messages of the given
283 * type will be discarded (and the connection closed)
284 * if they do not have the right size.
285 */
286 uint16_t expected_size;
287};
288
289
290/**
291 * Create a new message for MQ.
292 *
293 * @param mhp message header to store the allocated message header in, can be NULL
294 * @param size size of the message to allocate
295 * @param type type of the message, will be set in the allocated message
296 * @return the allocated MQ message
297 */
298struct GNUNET_MQ_Message *
299GNUNET_MQ_msg_ (struct GNUNET_MessageHeader **mhp, uint16_t size, uint16_t type);
300
301
302/**
303 * Resize the the mq message pointed to by mqmp,
304 * and append the given data to it.
305 *
306 * @param mqmp pointer to a mq message pointer
307 * @param src source of the data to append
308 * @param len length of the data to append
309 * @return GNUNET_OK on success,
310 * GNUNET_SYSERR on error (e.g. if len is too large)
311 */
312int
313GNUNET_MQ_nest_ (struct GNUNET_MQ_Message **mqmp,
314 const void *src, uint16_t len);
315
316
317/**
318 * Discard the message queue message, free all
319 * allocated resources. Must be called in the event
320 * that a message is created but should not actually be sent.
321 *
322 * @param mqm the message to discard
323 */
324void
325GNUNET_MQ_discard (struct GNUNET_MQ_Message *mqm);
326
327
328/**
329 * Send a message with the give message queue.
330 * May only be called once per message.
331 *
332 * @param mq message queue
333 * @param mqm the message to send.
334 */
335void
336GNUNET_MQ_send (struct GNUNET_MQ_MessageQueue *mq, struct GNUNET_MQ_Message *mqm);
337
338
339/**
340 * Cancel sending the message. Message must have been sent with GNUNET_MQ_send before.
341 * May not be called after the notify sent callback has been called
342 *
343 * @param mqm queued message to cancel
344 */
345void
346GNUNET_MQ_send_cancel (struct GNUNET_MQ_Message *mqm);
347
348
349/**
350 * Associate the assoc_data in mq with a unique request id.
351 *
352 * @param mq message queue, id will be unique for the queue
353 * @param mqm message to associate
354 * @param assoc_data to associate
355 */
356uint32_t
357GNUNET_MQ_assoc_add (struct GNUNET_MQ_MessageQueue *mq,
358 struct GNUNET_MQ_Message *mqm,
359 void *assoc_data);
360
361/**
362 * Get the data associated with a request id in a queue
363 *
364 * @param mq the message queue with the association
365 * @param request_id the request id we are interested in
366 * @return the associated data
367 */
368void *
369GNUNET_MQ_assoc_get (struct GNUNET_MQ_MessageQueue *mq, uint32_t request_id);
370
371
372/**
373 * Remove the association for a request id
374 *
375 * @param mq the message queue with the association
376 * @param request_id the request id we want to remove
377 * @return the associated data
378 */
379void *
380GNUNET_MQ_assoc_remove (struct GNUNET_MQ_MessageQueue *mq, uint32_t request_id);
381
382
383
384/**
385 * Create a message queue for a GNUNET_CLIENT_Connection.
386 * If handlers are specfied, receive messages from the connection.
387 *
388 * @param connection the client connection
389 * @param handlers handlers for receiving messages
390 * @param cls closure for the handlers
391 * @return the message queue
392 */
393struct GNUNET_MQ_MessageQueue *
394GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection,
395 const struct GNUNET_MQ_Handler *handlers,
396 void *cls);
397
398
399/**
400 * Create a message queue for a GNUNET_STREAM_Socket.
401 *
402 * @param client the client
403 * @return the message queue
404 */
405struct GNUNET_MQ_MessageQueue *
406GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client);
407
408
409/**
410 * Create a message queue for the specified handlers.
411 *
412 * @param send function the implements sending messages
413 * @param destroy function that implements destroying the queue
414 * @param state for the queue, passed to 'send' and 'destroy'
415 * @param handlers array of message handlers
416 * @param error_handler handler for read and write errors
417 * @return a new message queue
418 */
419struct GNUNET_MQ_MessageQueue *
420GNUNET_MQ_queue_for_callbacks (GNUNET_MQ_SendImpl send,
421 GNUNET_MQ_DestroyImpl destroy,
422 void *impl_state,
423 struct GNUNET_MQ_Handler *handlers,
424 GNUNET_MQ_ErrorHandler error_handler,
425 void *cls);
426
427
428
429/**
430 * Replace the handlers of a message queue with new handlers.
431 * Takes effect immediately, even for messages that already have been received, but for
432 * with the handler has not been called.
433 *
434 * @param mq message queue
435 * @param new_handlers new handlers
436 * @param cls new closure for the handlers
437 */
438void
439GNUNET_MQ_replace_handlers (struct GNUNET_MQ_MessageQueue *mq,
440 const struct GNUNET_MQ_Handler *new_handlers,
441 void *cls);
442
443
444/**
445 * Call a callback once the message has been sent, that is, the message
446 * can not be canceled anymore.
447 * There can be only one notify sent callback per message.
448 *
449 * @param mqm message to call the notify callback for
450 * @param cb the notify callback
451 * @param cls closure for the callback
452 */
453void
454GNUNET_MQ_notify_sent (struct GNUNET_MQ_Message *mqm,
455 GNUNET_MQ_NotifyCallback cb,
456 void *cls);
457
458
459/**
460 * Destroy the message queue.
461 *
462 * @param mq message queue to destroy
463 */
464void
465GNUNET_MQ_destroy (struct GNUNET_MQ_MessageQueue *mq);
466
467
468/**
469 * Call the right callback for a message.
470 *
471 * @param mq message queue with the handlers
472 * @param mh message to dispatch
473 */
474void
475GNUNET_MQ_dispatch (struct GNUNET_MQ_MessageQueue *mq,
476 const struct GNUNET_MessageHeader *mh);
477
478#endif