aboutsummaryrefslogtreecommitdiff
path: root/src/util/op.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/op.c')
-rw-r--r--src/util/op.c334
1 files changed, 0 insertions, 334 deletions
diff --git a/src/util/op.c b/src/util/op.c
deleted file mode 100644
index 647fedb53..000000000
--- a/src/util/op.c
+++ /dev/null
@@ -1,334 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2016 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file
23 * Asynchronous operations; register callbacks for operations and call them when a response arrives.
24 *
25 * @author Gabor X Toth
26 */
27
28#include <inttypes.h>
29
30#include "platform.h"
31#include "gnunet_util_lib.h"
32
33#define LOG(kind, ...) GNUNET_log_from (kind, "util-op", __VA_ARGS__)
34
35struct OperationListItem
36{
37 struct OperationListItem *prev;
38 struct OperationListItem *next;
39
40 /**
41 * Operation ID.
42 */
43 uint64_t op_id;
44
45 /**
46 * Continuation to invoke with the result of an operation.
47 */
48 GNUNET_ResultCallback result_cb;
49
50 /**
51 * Closure for @a result_cb.
52 */
53 void *cls;
54
55 /**
56 * User context.
57 */
58 void *ctx;
59};
60
61
62/**
63 * Operations handle.
64 */
65
66struct GNUNET_OP_Handle
67{
68 /**
69 * First operation in the linked list.
70 */
71 struct OperationListItem *op_head;
72
73 /**
74 * Last operation in the linked list.
75 */
76 struct OperationListItem *op_tail;
77
78 /**
79 * Last operation ID used.
80 */
81 uint64_t last_op_id;
82};
83
84
85/**
86 * Create new operations handle.
87 */
88struct GNUNET_OP_Handle *
89GNUNET_OP_create ()
90{
91 return GNUNET_new (struct GNUNET_OP_Handle);
92}
93
94
95/**
96 * Destroy operations handle.
97 */
98void
99GNUNET_OP_destroy (struct GNUNET_OP_Handle *h)
100{
101 GNUNET_free (h);
102}
103
104
105/**
106 * Get a unique operation ID to distinguish between asynchronous requests.
107 *
108 * @param h
109 * Operations handle.
110 *
111 * @return Operation ID to use.
112 */
113uint64_t
114GNUNET_OP_get_next_id (struct GNUNET_OP_Handle *h)
115{
116 return ++h->last_op_id;
117}
118
119
120/**
121 * Find operation by ID.
122 *
123 * @param h
124 * Operations handle.
125 * @param op_id
126 * Operation ID to look up.
127 *
128 * @return Operation, or NULL if not found.
129 */
130static struct OperationListItem *
131op_find (struct GNUNET_OP_Handle *h,
132 uint64_t op_id)
133{
134 struct OperationListItem *op;
135
136 for (op = h->op_head; NULL != op; op = op->next)
137 if (op->op_id == op_id)
138 return op;
139 return NULL;
140}
141
142
143/**
144 * Find operation by ID.
145 *
146 * @param h
147 * Operations handle.
148 * @param op_id
149 * Operation ID to look up.
150 * @param[out] result_cb
151 * If an operation was found, its result callback is returned here.
152 * @param[out] cls
153 * If an operation was found, its closure is returned here.
154 * @param[out] ctx
155 * If an operation was found, its user context is returned here.
156 *
157 * @return #GNUNET_YES if an operation was found,
158 * #GNUNET_NO if not found.
159 */
160int
161GNUNET_OP_get (struct GNUNET_OP_Handle *h,
162 uint64_t op_id,
163 GNUNET_ResultCallback *result_cb,
164 void **cls,
165 void **ctx)
166{
167 struct OperationListItem *op = op_find (h, op_id);
168
169 if (NULL != op)
170 {
171 if (NULL != result_cb)
172 *result_cb = op->result_cb;
173 if (NULL != cls)
174 *cls = op->cls;
175 if (NULL != ctx)
176 *ctx = op->ctx;
177 return GNUNET_YES;
178 }
179 return GNUNET_NO;
180}
181
182
183/**
184 * Add a new operation.
185 *
186 * @param h
187 * Operations handle.
188 * @param result_cb
189 * Function to call with the result of the operation.
190 * @param cls
191 * Closure for @a result_cb.
192 * @param ctx
193 * User context.
194 *
195 * @return ID of the new operation.
196 */
197uint64_t
198GNUNET_OP_add (struct GNUNET_OP_Handle *h,
199 GNUNET_ResultCallback result_cb,
200 void *cls,
201 void *ctx)
202{
203 struct OperationListItem *op;
204
205 op = GNUNET_new (struct OperationListItem);
206 op->op_id = GNUNET_OP_get_next_id (h);
207 op->result_cb = result_cb;
208 op->cls = cls;
209 op->ctx = ctx;
210 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
211 h->op_tail,
212 op);
213 LOG (GNUNET_ERROR_TYPE_DEBUG,
214 "%p Added operation #%" PRIu64 "\n",
215 h, op->op_id);
216 return op->op_id;
217}
218
219
220/**
221 * Remove an operation, and call its result callback (unless it was cancelled).
222 *
223 *
224 * @param h
225 * Operations handle.
226 * @param op_id
227 * Operation ID.
228 * @param result_code
229 * Result of the operation.
230 * @param data
231 * Data result of the operation.
232 * @param data_size
233 * Size of @a data.
234 * @param[out] ctx
235 * User context.
236 * @param cancel
237 * Is the operation cancelled?
238 * #GNUNET_NO Not cancelled, result callback is called.
239 * #GNUNET_YES Cancelled, result callback is not called.
240 *
241 * @return #GNUNET_YES if the operation was found and removed,
242 * #GNUNET_NO if the operation was not found.
243 */
244static int
245op_result (struct GNUNET_OP_Handle *h,
246 uint64_t op_id,
247 int64_t result_code,
248 const void *data,
249 uint16_t data_size,
250 void **ctx,
251 uint8_t cancel)
252{
253 if (0 == op_id)
254 return GNUNET_NO;
255
256 struct OperationListItem *op = op_find (h, op_id);
257 if (NULL == op)
258 {
259 LOG (GNUNET_ERROR_TYPE_WARNING,
260 "Could not find operation #%" PRIu64 "\n", op_id);
261 return GNUNET_NO;
262 }
263
264 if (NULL != ctx)
265 *ctx = op->ctx;
266
267 GNUNET_CONTAINER_DLL_remove (h->op_head,
268 h->op_tail,
269 op);
270
271 if ((GNUNET_YES != cancel) &&
272 (NULL != op->result_cb))
273 op->result_cb (op->cls,
274 result_code, data,
275 data_size);
276 GNUNET_free (op);
277 return GNUNET_YES;
278}
279
280
281/**
282 * Call the result callback of an operation and remove it.
283 *
284 * @param h
285 * Operations handle.
286 * @param op_id
287 * Operation ID.
288 * @param result_code
289 * Result of the operation.
290 * @param data
291 * Data result of the operation.
292 * @param data_size
293 * Size of @a data.
294 * @param[out] ctx
295 * User context.
296 *
297 * @return #GNUNET_YES if the operation was found and removed,
298 * #GNUNET_NO if the operation was not found.
299 */
300int
301GNUNET_OP_result (struct GNUNET_OP_Handle *h,
302 uint64_t op_id,
303 int64_t result_code,
304 const void *data,
305 uint16_t data_size,
306 void **ctx)
307{
308 LOG (GNUNET_ERROR_TYPE_DEBUG,
309 "%p Received result for operation #%" PRIu64 ": %" PRId64 " (size: %u)\n",
310 h, op_id, result_code, data_size);
311 return op_result (h, op_id, result_code, data, data_size, ctx, GNUNET_NO);
312}
313
314
315/**
316 * Remove / cancel an operation.
317 *
318 * @param h
319 * Operations handle.
320 * @param op_id
321 * Operation ID.
322 *
323 * @return #GNUNET_YES if the operation was found and removed,
324 * #GNUNET_NO if the operation was not found.
325 */
326int
327GNUNET_OP_remove (struct GNUNET_OP_Handle *h,
328 uint64_t op_id)
329{
330 LOG (GNUNET_ERROR_TYPE_DEBUG,
331 "%p Cancelling operation #%" PRIu64 "\n",
332 h, op_id);
333 return op_result (h, op_id, 0, NULL, 0, NULL, GNUNET_YES);
334}