work on gnunet-set, isolated bug in stream
[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 mq/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 #define GNUNET_MQ_nest(mqm, mh) GNUNET_MQ_nest_ (&mqm, mh)
62
63 /**
64  * Allocate a GNUNET_MQ_Message, where the message only consists of a header.
65  * The allocated message will already have the type and size field set.
66  *
67  * @param mvar variable to store the allocated message in;
68  *             must have a header field
69  * @param type type of the message
70  */
71 #define GNUNET_MQ_msg_header(type) GNUNET_MQ_msg_ (NULL, sizeof (struct GNUNET_MessageHeader), type)
72
73
74 /**
75  * Allocate a GNUNET_MQ_Message, where the message only consists of a header and extra space.
76  * The allocated message will already have the type and size field set.
77  *
78  * @param mvar variable to store the allocated message in;
79  *             must have a header field
80  * @param esize extra space to allocate after the message header
81  * @param type type of the message
82  */
83 #define GNUNET_MQ_msg_header_extra(mh, esize, type) GNUNET_MQ_msg_ (&mh, sizeof (struct GNUNET_MessageHeader), type)
84
85
86 /**
87  * End-marker for the handlers array
88  */
89 #define GNUNET_MQ_HANDLERS_END {NULL, 0}
90
91 /**
92  * Opaque handle to a message queue
93  */
94 struct GNUNET_MQ_MessageQueue;
95
96 /**
97  * Opaque handle to an allocated message
98  */
99 struct GNUNET_MQ_Message; // Entry (/ Request)
100
101 /**
102  * Called when a message has been received.
103  *
104  * @param cls closure
105  * @param msg the received message
106  */
107 typedef void (*GNUNET_MQ_MessageCallback) (void *cls, const struct GNUNET_MessageHeader *msg);
108
109
110 /**
111  * Message handler for a specific message type.
112  */
113 struct GNUNET_MQ_Handler
114 {
115   /**
116    * Callback, called every time a new message of 
117    * the specified type has been receied.
118    */
119   GNUNET_MQ_MessageCallback cb;
120
121
122   /**
123    * Type of the message we are interested in
124    */
125   uint16_t type;
126 };
127
128 /**
129  * Callback used for notifications
130  *
131  * @param cls closure
132  */
133 typedef void (*GNUNET_MQ_NotifyCallback) (void *cls);
134
135 /**
136  * Create a new message for MQ.
137  * 
138  * @param mhp message header to store the allocated message header in, can be NULL
139  * @param size size of the message to allocate
140  * @param type type of the message, will be set in the allocated message
141  * @return the allocated MQ message
142  */
143 struct GNUNET_MQ_Message *
144 GNUNET_MQ_msg_ (struct GNUNET_MessageHeader **mhp, uint16_t size, uint16_t type);
145
146
147 int
148 GNUNET_MQ_nest_ (struct GNUNET_MQ_Message **mqmp,
149                  const struct GNUNET_MessageHeader *m);
150
151
152 /**
153  * Discard the message queue message, free all
154  * allocated resources. Must be called in the event
155  * that a message is created but should not actually be sent.
156  *
157  * @param mqm the message to discard
158  */
159 void
160 GNUNET_MQ_discard (struct GNUNET_MQ_Message *mqm);
161
162
163 /**
164  * Send a message with the give message queue.
165  * May only be called once per message.
166  * 
167  * @param mq message queue
168  * @param mqm the message to send.
169  */
170 void
171 GNUNET_MQ_send (struct GNUNET_MQ_MessageQueue *mq, struct GNUNET_MQ_Message *mqm);
172
173
174 /**
175  * Cancel sending the message. Message must have been sent with GNUNET_MQ_send before.
176  * May not be called after the notify sent callback has been called
177  *
178  * @param mqm queued message to cancel
179  */
180 void
181 GNUNET_MQ_send_cancel (struct GNUNET_MQ_Message *mqm);
182
183
184 /**
185  * Associate the assoc_data in mq with a unique request id.
186  *
187  * @param mq message queue, id will be unique for the queue
188  * @param mqm message to associate
189  * @param data to associate
190  */
191 uint32_t
192 GNUNET_MQ_assoc_add (struct GNUNET_MQ_MessageQueue *mq,
193                      struct GNUNET_MQ_Message *mqm,
194                      void *assoc_data);
195
196 /**
197  * Get the data associated with a request id in a queue
198  *
199  * @param mq the message queue with the association
200  * @param request_id the request id we are interested in
201  * @return the associated data
202  */
203 void *
204 GNUNET_MQ_assoc_get (struct GNUNET_MQ_MessageQueue *mq, uint32_t request_id);
205
206
207 /**
208  * Remove the association for a request id
209  *
210  * @param mq the message queue with the association
211  * @param request_id the request id we want to remove
212  * @return the associated data
213  */
214 void *
215 GNUNET_MQ_assoc_remove (struct GNUNET_MQ_MessageQueue *mq, uint32_t request_id);
216
217
218
219 /**
220  * Create a message queue for a GNUNET_CLIENT_Connection.
221  * If handlers are specfied, receive messages from the connection.
222  *
223  * @param connection the client connection
224  * @param handlers handlers for receiving messages
225  * @param cls closure for the handlers
226  * @return the message queue
227  */
228 struct GNUNET_MQ_MessageQueue *
229 GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection,
230                                        const struct GNUNET_MQ_Handler *handlers,
231                                        void *cls);
232
233
234 /**
235  * Create a message queue for a GNUNET_STREAM_Socket.
236  *
237  * @param param client the client
238  * @return the message queue
239  */
240 struct GNUNET_MQ_MessageQueue *
241 GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client);
242
243
244
245 /**
246  * Create a message queue for a GNUNET_STREAM_Socket.
247  * If handlers are specfied, receive messages from the stream socket.
248  *
249  * @param socket the stream socket
250  * @param handlers handlers for receiving messages
251  * @param cls closure for the handlers
252  * @return the message queue
253  */
254 struct GNUNET_MQ_MessageQueue *
255 GNUNET_MQ_queue_for_stream_socket (struct GNUNET_STREAM_Socket *socket,
256                                    const struct GNUNET_MQ_Handler *handlers,
257                                    void *cls);
258
259 /**
260  * Replace the handlers of a message queue with new handlers.
261  * Takes effect immediately, even for messages that already have been received, but for
262  * with the handler has not been called.
263  *
264  * @param mq message queue
265  * @param new_handlers new handlers
266  * @param cls new closure for the handlers
267  */
268 void
269 GNUNET_MQ_replace_handlers (struct GNUNET_MQ_MessageQueue *mq,
270                             const struct GNUNET_MQ_Handler *new_handlers,
271                             void *cls);
272
273
274
275 /**
276  * Call a callback once the message has been sent, that is, the message
277  * can not be canceled anymore.
278  * There can be only one notify sent callback per message.
279  *
280  * @param mqm message to call the notify callback for
281  * @param cb the notify callback
282  * @param cls closure for the callback
283  */
284 void
285 GNUNET_MQ_notify_sent (struct GNUNET_MQ_Message *mqm,
286                        GNUNET_MQ_NotifyCallback cb,
287                        void *cls);
288
289
290 /**
291  * Destroy the message queue.
292  *
293  * @param mq message queue to destroy
294  */
295 void
296 GNUNET_MQ_destroy (struct GNUNET_MQ_MessageQueue *mq);
297
298 #endif