2 This file is part of GNUnet.
3 (C) 2012 Christian Grothoff (and other contributing authors)
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.
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.
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.
22 * @author Florian Dold
24 * @brief general purpose request queue
30 #include "gnunet_common.h"
31 #include "gnunet_util_lib.h"
32 #include "gnunet_connection_lib.h"
33 #include "gnunet_server_lib.h"
34 #include "gnunet_stream_lib.h"
38 * Allocate a GNUNET_MQ_Message, with extra space allocated after the space needed
39 * by the message struct.
40 * The allocated message will already have the type and size field set.
42 * @param mvar variable to store the allocated message in;
43 * must have a header field
44 * @param esize extra space to allocate after the message
45 * @param type type of the message
46 * @return the MQ message
48 #define GNUNET_MQ_msg_extra(mvar, esize, type) GNUNET_MQ_msg_((((void)(mvar)->header), (struct GNUNET_MessageHeader**) &(mvar)), (esize) + sizeof *(mvar), (type))
51 * Allocate a GNUNET_MQ_Message.
52 * The allocated message will already have the type and size field set.
54 * @param mvar variable to store the allocated message in;
55 * must have a header field
56 * @param type type of the message
57 * @return the MQ message
59 #define GNUNET_MQ_msg(mvar, type) GNUNET_MQ_msg_extra(mvar, 0, type)
62 * Append data to the end of an existing MQ message.
63 * If the operation is successful, mqm is changed to point to the new MQ message,
64 * and GNUNET_OK is returned.
65 * On failure, GNUNET_SYSERR is returned, and the pointer mqm is not changed,
66 * the user of this API must take care of disposing the already allocated message
67 * (either by sending it, or by using GNUNET_MQ_discard)
69 * @param mqm MQ message to augment with additional data
70 * @param src source buffer for the additional data
71 * @param len length of the additional data
74 #define GNUNET_MQ_nest(mqm, src, len) GNUNET_MQ_nest_ (&mqm, src, len)
79 * Append a message to the end of an existing MQ message.
80 * If the operation is successful, mqm is changed to point to the new MQ message,
81 * and GNUNET_OK is returned.
82 * On failure, GNUNET_SYSERR is returned, and the pointer mqm is not changed,
83 * the user of this API must take care of disposing the already allocated message
84 * (either by sending it, or by using GNUNET_MQ_discard)
86 * @param mqm MQ message to augment with additional data
87 * @param mh the message to append, must be of type 'struct GNUNET_MessageHeader *'
89 #define GNUNET_MQ_nest_mh(mqm, mh) ((NULL == mh) ? (GNUNET_OK) : GNUNET_MQ_nest((mqm), (mh), ntohs ((mh)->size)))
93 * Allocate a GNUNET_MQ_Message, where the message only consists of a header.
94 * The allocated message will already have the type and size field set.
96 * @param type type of the message
98 #define GNUNET_MQ_msg_header(type) GNUNET_MQ_msg_ (NULL, sizeof (struct GNUNET_MessageHeader), type)
102 * Allocate a GNUNET_MQ_Message, where the message only consists of a header and extra space.
103 * The allocated message will already have the type and size field set.
105 * @param mh pointer that will changed to point at to the allocated message header
106 * @param esize extra space to allocate after the message header
107 * @param type type of the message
109 #define GNUNET_MQ_msg_header_extra(mh, esize, type) GNUNET_MQ_msg_ (&mh, sizeof (struct GNUNET_MessageHeader), type)
113 * End-marker for the handlers array
115 #define GNUNET_MQ_HANDLERS_END {NULL, 0, 0}
118 * Opaque handle to a message queue
120 struct GNUNET_MQ_MessageQueue;
123 * Opaque handle to an allocated message
125 struct GNUNET_MQ_Message; // Entry (/ Request)
128 * Called when a message has been received.
131 * @param msg the received message
133 typedef void (*GNUNET_MQ_MessageCallback) (void *cls, const struct GNUNET_MessageHeader *msg);
137 * Message handler for a specific message type.
139 struct GNUNET_MQ_Handler
142 * Callback, called every time a new message of
143 * the specified type has been receied.
145 GNUNET_MQ_MessageCallback cb;
149 * Type of the message this handler covers.
154 * Expected size of messages of this type. Use 0 for
155 * variable-size. If non-zero, messages of the given
156 * type will be discarded (and the connection closed)
157 * if they do not have the right size.
159 uint16_t expected_size;
163 * Callback used for notifications
167 typedef void (*GNUNET_MQ_NotifyCallback) (void *cls);
170 * Create a new message for MQ.
172 * @param mhp message header to store the allocated message header in, can be NULL
173 * @param size size of the message to allocate
174 * @param type type of the message, will be set in the allocated message
175 * @return the allocated MQ message
177 struct GNUNET_MQ_Message *
178 GNUNET_MQ_msg_ (struct GNUNET_MessageHeader **mhp, uint16_t size, uint16_t type);
182 GNUNET_MQ_nest_ (struct GNUNET_MQ_Message **mqmp,
183 const void *src, uint16_t len);
187 * Discard the message queue message, free all
188 * allocated resources. Must be called in the event
189 * that a message is created but should not actually be sent.
191 * @param mqm the message to discard
194 GNUNET_MQ_discard (struct GNUNET_MQ_Message *mqm);
198 * Send a message with the give message queue.
199 * May only be called once per message.
201 * @param mq message queue
202 * @param mqm the message to send.
205 GNUNET_MQ_send (struct GNUNET_MQ_MessageQueue *mq, struct GNUNET_MQ_Message *mqm);
209 * Cancel sending the message. Message must have been sent with GNUNET_MQ_send before.
210 * May not be called after the notify sent callback has been called
212 * @param mqm queued message to cancel
215 GNUNET_MQ_send_cancel (struct GNUNET_MQ_Message *mqm);
219 * Associate the assoc_data in mq with a unique request id.
221 * @param mq message queue, id will be unique for the queue
222 * @param mqm message to associate
223 * @param assoc_data to associate
226 GNUNET_MQ_assoc_add (struct GNUNET_MQ_MessageQueue *mq,
227 struct GNUNET_MQ_Message *mqm,
231 * Get the data associated with a request id in a queue
233 * @param mq the message queue with the association
234 * @param request_id the request id we are interested in
235 * @return the associated data
238 GNUNET_MQ_assoc_get (struct GNUNET_MQ_MessageQueue *mq, uint32_t request_id);
242 * Remove the association for a request id
244 * @param mq the message queue with the association
245 * @param request_id the request id we want to remove
246 * @return the associated data
249 GNUNET_MQ_assoc_remove (struct GNUNET_MQ_MessageQueue *mq, uint32_t request_id);
254 * Create a message queue for a GNUNET_CLIENT_Connection.
255 * If handlers are specfied, receive messages from the connection.
257 * @param connection the client connection
258 * @param handlers handlers for receiving messages
259 * @param cls closure for the handlers
260 * @return the message queue
262 struct GNUNET_MQ_MessageQueue *
263 GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection,
264 const struct GNUNET_MQ_Handler *handlers,
269 * Create a message queue for a GNUNET_STREAM_Socket.
271 * @param client the client
272 * @return the message queue
274 struct GNUNET_MQ_MessageQueue *
275 GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client);
280 * Create a message queue for a GNUNET_STREAM_Socket.
281 * If handlers are specfied, receive messages from the stream socket.
283 * @param socket the stream socket
284 * @param handlers handlers for receiving messages
285 * @param cls closure for the handlers
286 * @return the message queue
288 struct GNUNET_MQ_MessageQueue *
289 GNUNET_MQ_queue_for_stream_socket (struct GNUNET_STREAM_Socket *socket,
290 const struct GNUNET_MQ_Handler *handlers,
294 * Replace the handlers of a message queue with new handlers.
295 * Takes effect immediately, even for messages that already have been received, but for
296 * with the handler has not been called.
298 * @param mq message queue
299 * @param new_handlers new handlers
300 * @param cls new closure for the handlers
303 GNUNET_MQ_replace_handlers (struct GNUNET_MQ_MessageQueue *mq,
304 const struct GNUNET_MQ_Handler *new_handlers,
310 * Call a callback once the message has been sent, that is, the message
311 * can not be canceled anymore.
312 * There can be only one notify sent callback per message.
314 * @param mqm message to call the notify callback for
315 * @param cb the notify callback
316 * @param cls closure for the callback
319 GNUNET_MQ_notify_sent (struct GNUNET_MQ_Message *mqm,
320 GNUNET_MQ_NotifyCallback cb,
324 * Call a callback once all messages queued have been sent,
325 * i.e. the message queue is empty.
327 * @param mqm the message queue to send the notification for
328 * @param cb the callback to call on an empty queue
329 * @param cls closure for cb
332 GNUNET_MQ_notify_empty (struct GNUNET_MQ_MessageQueue *mqm,
333 GNUNET_MQ_NotifyCallback cb,
338 * Call a callback if reading encountered an error.
340 * @param mqm the message queue to send the notification for
341 * @param cb the callback to call on a read error
342 * @param cls closure for cb
345 GNUNET_MQ_notify_read_error (struct GNUNET_MQ_MessageQueue *mqm,
346 GNUNET_MQ_NotifyCallback cb,
351 * Destroy the message queue.
353 * @param mq message queue to destroy
356 GNUNET_MQ_destroy (struct GNUNET_MQ_MessageQueue *mq);