-comments
[oweals/gnunet.git] / src / set / mq.h
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 MQ_H
27 #define MQ_H
28
29 #include "platform.h"
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"
35
36
37 /**
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.
41  *
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
47  */
48 #define GNUNET_MQ_msg_extra(mvar, esize, type) GNUNET_MQ_msg_((((void)(mvar)->header), (struct GNUNET_MessageHeader**) &(mvar)), (esize) + sizeof *(mvar), (type))
49
50 /**
51  * Allocate a GNUNET_MQ_Message.
52  * The allocated message will already have the type and size field set.
53  *
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
58  */
59 #define GNUNET_MQ_msg(mvar, type) GNUNET_MQ_msg_extra(mvar, 0, type)
60
61 /**
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)
68  *
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
72  * @return FIXME
73  */
74 #define GNUNET_MQ_nest(mqm, src, len) GNUNET_MQ_nest_ (&mqm, src, len)
75
76
77
78 /**
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)
85  *
86  * @param mqm MQ message to augment with additional data
87  * @param mh the message to append, must be of type 'struct GNUNET_MessageHeader *'
88  */
89 #define GNUNET_MQ_nest_mh(mqm, mh) ((NULL == mh) ? (GNUNET_OK) : GNUNET_MQ_nest((mqm), (mh), ntohs ((mh)->size)))
90
91
92 /**
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.
95  *
96  * @param type type of the message
97  */
98 #define GNUNET_MQ_msg_header(type) GNUNET_MQ_msg_ (NULL, sizeof (struct GNUNET_MessageHeader), type)
99
100
101 /**
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.
104  *
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
108  */
109 #define GNUNET_MQ_msg_header_extra(mh, esize, type) GNUNET_MQ_msg_ (&mh, sizeof (struct GNUNET_MessageHeader), type)
110
111
112 /**
113  * End-marker for the handlers array
114  */
115 #define GNUNET_MQ_HANDLERS_END {NULL, 0, 0}
116
117 /**
118  * Opaque handle to a message queue
119  */
120 struct GNUNET_MQ_MessageQueue;
121
122 /**
123  * Opaque handle to an allocated message
124  */
125 struct GNUNET_MQ_Message; // Entry (/ Request)
126
127 /**
128  * Called when a message has been received.
129  *
130  * @param cls closure
131  * @param msg the received message
132  */
133 typedef void (*GNUNET_MQ_MessageCallback) (void *cls, const struct GNUNET_MessageHeader *msg);
134
135
136 /**
137  * Message handler for a specific message type.
138  */
139 struct GNUNET_MQ_Handler
140 {
141   /**
142    * Callback, called every time a new message of 
143    * the specified type has been receied.
144    */
145   GNUNET_MQ_MessageCallback cb;
146
147
148   /**
149    * Type of the message this handler covers.
150    */
151   uint16_t type;
152
153   /**
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.
158    */
159   uint16_t expected_size;
160 };
161
162 /**
163  * Callback used for notifications
164  *
165  * @param cls closure
166  */
167 typedef void (*GNUNET_MQ_NotifyCallback) (void *cls);
168
169 /**
170  * Create a new message for MQ.
171  * 
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
176  */
177 struct GNUNET_MQ_Message *
178 GNUNET_MQ_msg_ (struct GNUNET_MessageHeader **mhp, uint16_t size, uint16_t type);
179
180
181 int
182 GNUNET_MQ_nest_ (struct GNUNET_MQ_Message **mqmp,
183                  const void *src, uint16_t len);
184
185
186 /**
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.
190  *
191  * @param mqm the message to discard
192  */
193 void
194 GNUNET_MQ_discard (struct GNUNET_MQ_Message *mqm);
195
196
197 /**
198  * Send a message with the give message queue.
199  * May only be called once per message.
200  * 
201  * @param mq message queue
202  * @param mqm the message to send.
203  */
204 void
205 GNUNET_MQ_send (struct GNUNET_MQ_MessageQueue *mq, struct GNUNET_MQ_Message *mqm);
206
207
208 /**
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
211  *
212  * @param mqm queued message to cancel
213  */
214 void
215 GNUNET_MQ_send_cancel (struct GNUNET_MQ_Message *mqm);
216
217
218 /**
219  * Associate the assoc_data in mq with a unique request id.
220  *
221  * @param mq message queue, id will be unique for the queue
222  * @param mqm message to associate
223  * @param assoc_data to associate
224  */
225 uint32_t
226 GNUNET_MQ_assoc_add (struct GNUNET_MQ_MessageQueue *mq,
227                      struct GNUNET_MQ_Message *mqm,
228                      void *assoc_data);
229
230 /**
231  * Get the data associated with a request id in a queue
232  *
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
236  */
237 void *
238 GNUNET_MQ_assoc_get (struct GNUNET_MQ_MessageQueue *mq, uint32_t request_id);
239
240
241 /**
242  * Remove the association for a request id
243  *
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
247  */
248 void *
249 GNUNET_MQ_assoc_remove (struct GNUNET_MQ_MessageQueue *mq, uint32_t request_id);
250
251
252
253 /**
254  * Create a message queue for a GNUNET_CLIENT_Connection.
255  * If handlers are specfied, receive messages from the connection.
256  *
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
261  */
262 struct GNUNET_MQ_MessageQueue *
263 GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection,
264                                        const struct GNUNET_MQ_Handler *handlers,
265                                        void *cls);
266
267
268 /**
269  * Create a message queue for a GNUNET_STREAM_Socket.
270  *
271  * @param client the client
272  * @return the message queue
273  */
274 struct GNUNET_MQ_MessageQueue *
275 GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client);
276
277
278
279 /**
280  * Create a message queue for a GNUNET_STREAM_Socket.
281  * If handlers are specfied, receive messages from the stream socket.
282  *
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
287  */
288 struct GNUNET_MQ_MessageQueue *
289 GNUNET_MQ_queue_for_stream_socket (struct GNUNET_STREAM_Socket *socket,
290                                    const struct GNUNET_MQ_Handler *handlers,
291                                    void *cls);
292
293 /**
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.
297  *
298  * @param mq message queue
299  * @param new_handlers new handlers
300  * @param cls new closure for the handlers
301  */
302 void
303 GNUNET_MQ_replace_handlers (struct GNUNET_MQ_MessageQueue *mq,
304                             const struct GNUNET_MQ_Handler *new_handlers,
305                             void *cls);
306
307
308
309 /**
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.
313  *
314  * @param mqm message to call the notify callback for
315  * @param cb the notify callback
316  * @param cls closure for the callback
317  */
318 void
319 GNUNET_MQ_notify_sent (struct GNUNET_MQ_Message *mqm,
320                        GNUNET_MQ_NotifyCallback cb,
321                        void *cls);
322
323 /**
324  * Call a callback once all messages queued have been sent,
325  * i.e. the message queue is empty.
326  *
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
330  */
331 void
332 GNUNET_MQ_notify_empty (struct GNUNET_MQ_MessageQueue *mqm,
333                         GNUNET_MQ_NotifyCallback cb,
334                         void *cls);
335
336
337 /**
338  * Call a callback if reading encountered an error.
339  *
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
343  */
344 void
345 GNUNET_MQ_notify_read_error (struct GNUNET_MQ_MessageQueue *mqm,
346                              GNUNET_MQ_NotifyCallback cb,
347                              void *cls);
348
349
350 /**
351  * Destroy the message queue.
352  *
353  * @param mq message queue to destroy
354  */
355 void
356 GNUNET_MQ_destroy (struct GNUNET_MQ_MessageQueue *mq);
357
358 #endif