removed unnecessary malloc
[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, (esize) + 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 /**
171  * Create a new message for MQ.
172  * 
173  * @param mhp message header to store the allocated message header in, can be NULL
174  * @param size size of the message to allocate
175  * @param type type of the message, will be set in the allocated message
176  * @return the allocated MQ message
177  */
178 struct GNUNET_MQ_Message *
179 GNUNET_MQ_msg_ (struct GNUNET_MessageHeader **mhp, uint16_t size, uint16_t type);
180
181
182 int
183 GNUNET_MQ_nest_ (struct GNUNET_MQ_Message **mqmp,
184                  const void *src, uint16_t len);
185
186
187 /**
188  * Discard the message queue message, free all
189  * allocated resources. Must be called in the event
190  * that a message is created but should not actually be sent.
191  *
192  * @param mqm the message to discard
193  */
194 void
195 GNUNET_MQ_discard (struct GNUNET_MQ_Message *mqm);
196
197
198 /**
199  * Send a message with the give message queue.
200  * May only be called once per message.
201  * 
202  * @param mq message queue
203  * @param mqm the message to send.
204  */
205 void
206 GNUNET_MQ_send (struct GNUNET_MQ_MessageQueue *mq, struct GNUNET_MQ_Message *mqm);
207
208
209 /**
210  * Cancel sending the message. Message must have been sent with GNUNET_MQ_send before.
211  * May not be called after the notify sent callback has been called
212  *
213  * @param mqm queued message to cancel
214  */
215 void
216 GNUNET_MQ_send_cancel (struct GNUNET_MQ_Message *mqm);
217
218
219 /**
220  * Associate the assoc_data in mq with a unique request id.
221  *
222  * @param mq message queue, id will be unique for the queue
223  * @param mqm message to associate
224  * @param assoc_data to associate
225  */
226 uint32_t
227 GNUNET_MQ_assoc_add (struct GNUNET_MQ_MessageQueue *mq,
228                      struct GNUNET_MQ_Message *mqm,
229                      void *assoc_data);
230
231 /**
232  * Get the data associated with a request id in a queue
233  *
234  * @param mq the message queue with the association
235  * @param request_id the request id we are interested in
236  * @return the associated data
237  */
238 void *
239 GNUNET_MQ_assoc_get (struct GNUNET_MQ_MessageQueue *mq, uint32_t request_id);
240
241
242 /**
243  * Remove the association for a request id
244  *
245  * @param mq the message queue with the association
246  * @param request_id the request id we want to remove
247  * @return the associated data
248  */
249 void *
250 GNUNET_MQ_assoc_remove (struct GNUNET_MQ_MessageQueue *mq, uint32_t request_id);
251
252
253
254 /**
255  * Create a message queue for a GNUNET_CLIENT_Connection.
256  * If handlers are specfied, receive messages from the connection.
257  *
258  * @param connection the client connection
259  * @param handlers handlers for receiving messages
260  * @param cls closure for the handlers
261  * @return the message queue
262  */
263 struct GNUNET_MQ_MessageQueue *
264 GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection,
265                                        const struct GNUNET_MQ_Handler *handlers,
266                                        void *cls);
267
268
269 /**
270  * Create a message queue for a GNUNET_STREAM_Socket.
271  *
272  * @param client the client
273  * @return the message queue
274  */
275 struct GNUNET_MQ_MessageQueue *
276 GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client);
277
278
279
280 /**
281  * Create a message queue for a GNUNET_STREAM_Socket.
282  * If handlers are specfied, receive messages from the stream socket.
283  *
284  * @param socket the stream socket
285  * @param handlers handlers for receiving messages
286  * @param cls closure for the handlers
287  * @return the message queue
288  */
289 struct GNUNET_MQ_MessageQueue *
290 GNUNET_MQ_queue_for_stream_socket (struct GNUNET_STREAM_Socket *socket,
291                                    const struct GNUNET_MQ_Handler *handlers,
292                                    void *cls);
293
294 /**
295  * Replace the handlers of a message queue with new handlers.
296  * Takes effect immediately, even for messages that already have been received, but for
297  * with the handler has not been called.
298  *
299  * @param mq message queue
300  * @param new_handlers new handlers
301  * @param cls new closure for the handlers
302  */
303 void
304 GNUNET_MQ_replace_handlers (struct GNUNET_MQ_MessageQueue *mq,
305                             const struct GNUNET_MQ_Handler *new_handlers,
306                             void *cls);
307
308
309
310 /**
311  * Call a callback once the message has been sent, that is, the message
312  * can not be canceled anymore.
313  * There can be only one notify sent callback per message.
314  *
315  * @param mqm message to call the notify callback for
316  * @param cb the notify callback
317  * @param cls closure for the callback
318  */
319 void
320 GNUNET_MQ_notify_sent (struct GNUNET_MQ_Message *mqm,
321                        GNUNET_MQ_NotifyCallback cb,
322                        void *cls);
323
324 /**
325  * Call a callback once all messages queued have been sent,
326  * i.e. the message queue is empty.
327  *
328  * @param mqm the message queue to send the notification for
329  * @param cb the callback to call on an empty queue
330  * @param cls closure for cb
331  */
332 void
333 GNUNET_MQ_notify_empty (struct GNUNET_MQ_MessageQueue *mqm,
334                         GNUNET_MQ_NotifyCallback cb,
335                         void *cls);
336
337
338 /**
339  * Call a callback if reading encountered an error.
340  *
341  * @param mqm the message queue to send the notification for
342  * @param cb the callback to call on a read error
343  * @param cls closure for cb
344  */
345 void
346 GNUNET_MQ_notify_read_error (struct GNUNET_MQ_MessageQueue *mqm,
347                              GNUNET_MQ_NotifyCallback cb,
348                              void *cls);
349
350
351 /**
352  * Destroy the message queue.
353  *
354  * @param mq message queue to destroy
355  */
356 void
357 GNUNET_MQ_destroy (struct GNUNET_MQ_MessageQueue *mq);
358
359 #endif