aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorGabor X Toth <*@tg-x.net>2016-09-22 11:35:35 +0000
committerGabor X Toth <*@tg-x.net>2016-09-22 11:35:35 +0000
commit7aaeecbba083f6e34f181fa3db515cf65736e9f6 (patch)
tree8a5b72b7ec28116dd2fcfdc6b48b41ea956a3748 /src/util
parentd4afc6e37a14fe3257263c377a243c1a22ed9ee5 (diff)
downloadgnunet-7aaeecbba083f6e34f181fa3db515cf65736e9f6.tar.gz
gnunet-7aaeecbba083f6e34f181fa3db515cf65736e9f6.zip
rm client_manager
Diffstat (limited to 'src/util')
-rw-r--r--src/util/Makefile.am1
-rw-r--r--src/util/client_manager.c841
2 files changed, 0 insertions, 842 deletions
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index fc2238650..2325874b2 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -60,7 +60,6 @@ libgnunetutil_la_SOURCES = \
60 bandwidth.c \ 60 bandwidth.c \
61 bio.c \ 61 bio.c \
62 client.c \ 62 client.c \
63 client_manager.c \
64 common_allocation.c \ 63 common_allocation.c \
65 common_endian.c \ 64 common_endian.c \
66 common_logging.c \ 65 common_logging.c \
diff --git a/src/util/client_manager.c b/src/util/client_manager.c
deleted file mode 100644
index f444ac24e..000000000
--- a/src/util/client_manager.c
+++ /dev/null
@@ -1,841 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V.
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 3, 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., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file util/client_manager.c
23 * @brief Client manager; higher level client API with transmission queue
24 * and message handler registration.
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-client-mgr", __VA_ARGS__)
34
35
36struct OperationListItem
37{
38 struct OperationListItem *prev;
39 struct OperationListItem *next;
40
41 /**
42 * Operation ID.
43 */
44 uint64_t op_id;
45
46 /**
47 * Continuation to invoke with the result of an operation.
48 */
49 GNUNET_ResultCallback result_cb;
50
51 /**
52 * Closure for @a result_cb.
53 */
54 void *cls;
55};
56
57
58/**
59 * List of arrays of message handlers.
60 */
61struct HandlersListItem
62{
63 struct HandlersListItem *prev;
64 struct HandlersListItem *next;
65
66 /**
67 * NULL-terminated array of handlers.
68 */
69 const struct GNUNET_CLIENT_MANAGER_MessageHandler *handlers;
70};
71
72
73struct MessageQueueItem
74{
75 struct MessageQueueItem *prev;
76 struct MessageQueueItem *next;
77 struct GNUNET_MessageHeader *msg;
78};
79
80
81struct GNUNET_CLIENT_MANAGER_Connection
82{
83 /**
84 * Configuration to use.
85 */
86 const struct GNUNET_CONFIGURATION_Handle *cfg;
87
88 /**
89 * Client connection to service.
90 */
91 struct GNUNET_CLIENT_Connection *client;
92
93 /**
94 * Currently pending transmission request, or NULL for none.
95 */
96 struct GNUNET_CLIENT_TransmitHandle *client_tmit;
97
98 /**
99 * Service name to connect to.
100 */
101 const char *service_name;
102
103 /**
104 * Head of messages to transmit to the service.
105 */
106 struct MessageQueueItem *tmit_head;
107
108 /**
109 * Tail of messages to transmit to the service.
110 */
111 struct MessageQueueItem *tmit_tail;
112
113 /**
114 * Message handlers.
115 */
116 const struct GNUNET_CLIENT_MANAGER_MessageHandler *handlers;
117
118 /**
119 * First operation in the linked list.
120 */
121 struct OperationListItem *op_head;
122
123 /**
124 * Last operation in the linked list.
125 */
126 struct OperationListItem *op_tail;
127
128 /**
129 * Last operation ID used.
130 */
131 uint64_t last_op_id;
132
133 /**
134 * Disconnect callback.
135 */
136 void (*disconnect_cb)(void *);
137
138 /**
139 * Disconnect closure.
140 */
141 void *disconnect_cls;
142
143 /**
144 * User context value.
145 * @see GNUNET_CLIENT_MANAGER_set_user_context()
146 * @see GNUNET_CLIENT_MANAGER_get_user_context()
147 */
148 void *user_ctx;
149
150 /**
151 * Last size given when user context was initialized.
152 * Used for sanity check.
153 */
154 size_t user_ctx_size;
155
156 /**
157 * Task doing exponential back-off trying to reconnect.
158 */
159 struct GNUNET_SCHEDULER_Task * reconnect_task;
160
161 /**
162 * Time for next connect retry.
163 */
164 struct GNUNET_TIME_Relative reconnect_delay;
165
166 /**
167 * Are we currently polling for incoming messages?
168 */
169 uint8_t in_receive;
170
171 /**
172 * #GNUNET_YES if GNUNET_CLIENT_MANAGER_disconnect() was called
173 * and we're transmitting the last messages from the queue.
174 */
175 uint8_t is_disconnecting;
176};
177
178
179/**
180 * Handle received messages from the service.
181 */
182static void
183recv_message (void *cls, const struct GNUNET_MessageHeader *msg)
184{
185 struct GNUNET_CLIENT_MANAGER_Connection *mgr = cls;
186 uint16_t type = 0, size = 0;
187
188 if (NULL != msg)
189 {
190 type = ntohs (msg->type);
191 size = ntohs (msg->size);
192 /* FIXME: decrease reconnect_delay gradually after a successful reconnection */
193 }
194 else /* disconnected */
195 {
196 mgr->client_tmit = NULL;
197 }
198
199 if (GNUNET_YES == mgr->is_disconnecting)
200 return;
201
202 size_t i = 0;
203 while (NULL != mgr->handlers[i].callback)
204 {
205 const struct GNUNET_CLIENT_MANAGER_MessageHandler *mh = &mgr->handlers[i];
206 if ((mh->type == type) || (mh->type == GNUNET_MESSAGE_TYPE_ALL))
207 {
208 if (0 != mh->expected_size
209 && ((GNUNET_NO == mh->is_variable_size && size != mh->expected_size)
210 || (GNUNET_YES == mh->is_variable_size && size < mh->expected_size)))
211 {
212 LOG (GNUNET_ERROR_TYPE_ERROR,
213 "Expected %u bytes for message of type %u, got %u.\n",
214 mh->expected_size, type, size);
215 GNUNET_break_op (0);
216 GNUNET_CLIENT_disconnect (mgr->client);
217 mgr->client = NULL;
218 recv_message (mgr, NULL);
219 break;
220 }
221 mh->callback (mh->callback_cls, mgr, msg);
222 }
223 i++;
224 }
225 if (NULL != mgr->client)
226 {
227 GNUNET_CLIENT_receive (mgr->client, &recv_message, mgr,
228 GNUNET_TIME_UNIT_FOREVER_REL);
229 }
230}
231
232
233/**
234 * Schedule transmission of the next message from our queue.
235 *
236 * @param mgr Client manager connection.
237 */
238static void
239transmit_next (struct GNUNET_CLIENT_MANAGER_Connection *mgr);
240
241
242static void
243schedule_disconnect (void *cls)
244{
245 struct GNUNET_CLIENT_MANAGER_Connection *mgr = cls;
246
247 GNUNET_CLIENT_MANAGER_disconnect (mgr, GNUNET_NO,
248 mgr->disconnect_cb,
249 mgr->disconnect_cls);
250}
251
252
253/**
254 * Transmit next message to service.
255 *
256 * @param cls
257 * struct GNUNET_CLIENT_MANAGER_Connection
258 * @param buf_size
259 * Number of bytes available in @a buf.
260 * @param buf
261 * Where to copy the message.
262 *
263 * @return Number of bytes copied to @a buf.
264 */
265static size_t
266send_next_message (void *cls, size_t buf_size, void *buf)
267{
268 struct GNUNET_CLIENT_MANAGER_Connection *mgr = cls;
269
270 LOG (GNUNET_ERROR_TYPE_DEBUG,
271 "send_next_message()\n");
272 if (NULL == buf)
273 {
274 /* disconnected */
275 recv_message (mgr, NULL);
276 return 0;
277 }
278
279 struct MessageQueueItem *mqi = mgr->tmit_head;
280 if (NULL == mqi)
281 return 0;
282
283 uint16_t size = ntohs (mqi->msg->size);
284 mgr->client_tmit = NULL;
285 GNUNET_assert (size <= buf_size);
286 GNUNET_memcpy (buf, mqi->msg, size);
287
288 GNUNET_CONTAINER_DLL_remove (mgr->tmit_head,
289 mgr->tmit_tail,
290 mqi);
291 GNUNET_free (mqi->msg);
292 GNUNET_free (mqi);
293
294 if (NULL != mgr->tmit_head)
295 {
296 transmit_next (mgr);
297 }
298 else if (GNUNET_YES == mgr->is_disconnecting)
299 {
300 (void) GNUNET_SCHEDULER_add_now (&schedule_disconnect, mgr);
301 return size;
302 }
303
304 if (GNUNET_NO == mgr->in_receive)
305 {
306 mgr->in_receive = GNUNET_YES;
307 GNUNET_CLIENT_receive (mgr->client, &recv_message, mgr,
308 GNUNET_TIME_UNIT_FOREVER_REL);
309 }
310 return size;
311}
312
313
314/**
315 * Schedule transmission of the next message from our queue.
316 *
317 * @param mgr Client manager connection.
318 */
319static void
320transmit_next (struct GNUNET_CLIENT_MANAGER_Connection *mgr)
321{
322 LOG (GNUNET_ERROR_TYPE_DEBUG, "transmit_next()\n");
323 if (NULL != mgr->client_tmit || NULL == mgr->client)
324 return;
325
326 if (NULL == mgr->tmit_head)
327 {
328 if (GNUNET_YES == mgr->is_disconnecting)
329 GNUNET_CLIENT_MANAGER_disconnect (mgr, GNUNET_NO,
330 mgr->disconnect_cb,
331 mgr->disconnect_cls);
332 return;
333 }
334
335 mgr->client_tmit
336 = GNUNET_CLIENT_notify_transmit_ready (mgr->client,
337 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
338 GNUNET_TIME_UNIT_FOREVER_REL,
339 GNUNET_NO,
340 &send_next_message,
341 mgr);
342}
343
344
345/**
346 * Try again to connect to the service.
347 *
348 * @param cls
349 * Channel handle.
350 */
351static void
352schedule_reconnect (void *cls)
353{
354 struct GNUNET_CLIENT_MANAGER_Connection *mgr = cls;
355
356 mgr->reconnect_task = NULL;
357 LOG (GNUNET_ERROR_TYPE_DEBUG,
358 "Connecting to %s service.\n",
359 mgr->service_name);
360 GNUNET_assert (NULL == mgr->client);
361 mgr->client = GNUNET_CLIENT_connect (mgr->service_name,
362 mgr->cfg);
363 GNUNET_assert (NULL != mgr->client);
364 transmit_next (mgr);
365}
366
367
368/**
369 * Connect to service.
370 *
371 * @param cfg
372 * Configuration to use.
373 * @param service_name
374 * Service name to connect to.
375 * @param handlers
376 * Message handlers.
377 *
378 * @return Client manager connection handle.
379 */
380struct GNUNET_CLIENT_MANAGER_Connection *
381GNUNET_CLIENT_MANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
382 const char *service_name,
383 const struct GNUNET_CLIENT_MANAGER_MessageHandler *handlers)
384{
385 struct GNUNET_CLIENT_MANAGER_Connection *mgr;
386
387 mgr = GNUNET_new (struct GNUNET_CLIENT_MANAGER_Connection);
388 mgr->cfg = cfg;
389 mgr->service_name = service_name;
390 mgr->handlers = handlers;
391 mgr->reconnect_delay = GNUNET_TIME_UNIT_ZERO;
392 mgr->reconnect_task = GNUNET_SCHEDULER_add_now (&schedule_reconnect,
393 mgr);
394 return mgr;
395}
396
397
398/**
399 * Disconnect from the service.
400 *
401 * @param mgr
402 * Client manager connection.
403 * @param transmit_queue
404 * Transmit pending messages in queue before disconnecting.
405 * @param disconnect_cb
406 * Function called after disconnected from the service.
407 * @param cls
408 * Closure for @a disconnect_cb.
409 */
410void
411GNUNET_CLIENT_MANAGER_disconnect (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
412 int transmit_queue,
413 GNUNET_ContinuationCallback disconnect_cb,
414 void *cls)
415{
416 LOG (GNUNET_ERROR_TYPE_DEBUG,
417 "Disconnecting (%d)\n",
418 transmit_queue);
419 mgr->disconnect_cb = disconnect_cb;
420 mgr->disconnect_cls = cls;
421 if (NULL != mgr->tmit_head)
422 {
423 if (GNUNET_YES == transmit_queue)
424 {
425 mgr->is_disconnecting = GNUNET_YES;
426 transmit_next (mgr);
427 return;
428 }
429 else
430 {
431 LOG (GNUNET_ERROR_TYPE_DEBUG,
432 "Disconnecting while there are still messages "
433 "in the transmission queue.\n");
434 GNUNET_CLIENT_MANAGER_drop_queue (mgr);
435 }
436 }
437 if (NULL != mgr->reconnect_task)
438 {
439 GNUNET_SCHEDULER_cancel (mgr->reconnect_task);
440 mgr->reconnect_task = NULL;
441 }
442 if (NULL != mgr->client_tmit)
443 {
444 GNUNET_CLIENT_notify_transmit_ready_cancel (mgr->client_tmit);
445 mgr->client_tmit = NULL;
446 }
447 if (NULL != mgr->client)
448 {
449 GNUNET_CLIENT_disconnect (mgr->client);
450 mgr->client = NULL;
451 }
452 if (NULL != mgr->disconnect_cb)
453 mgr->disconnect_cb (mgr->disconnect_cls);
454 GNUNET_free (mgr);
455 LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnected.\n");
456}
457
458
459/**
460 * Reschedule connect to the service using exponential back-off.
461 *
462 * @param mgr
463 * Client manager connection.
464 */
465void
466GNUNET_CLIENT_MANAGER_reconnect (struct GNUNET_CLIENT_MANAGER_Connection *mgr)
467{
468 if (NULL != mgr->reconnect_task)
469 return;
470
471 if (NULL != mgr->client_tmit)
472 {
473 GNUNET_CLIENT_notify_transmit_ready_cancel (mgr->client_tmit);
474 mgr->client_tmit = NULL;
475 }
476 if (NULL != mgr->client)
477 {
478 GNUNET_CLIENT_disconnect (mgr->client);
479 mgr->client = NULL;
480 }
481 mgr->in_receive = GNUNET_NO;
482 LOG (GNUNET_ERROR_TYPE_DEBUG,
483 "Scheduling task to reconnect to service in %s.\n",
484 GNUNET_STRINGS_relative_time_to_string (mgr->reconnect_delay, GNUNET_YES));
485 mgr->reconnect_task =
486 GNUNET_SCHEDULER_add_delayed (mgr->reconnect_delay,
487 &schedule_reconnect,
488 mgr);
489 mgr->reconnect_delay = GNUNET_TIME_STD_BACKOFF (mgr->reconnect_delay);
490}
491
492
493/**
494 * Add a message to the end of the transmission queue.
495 *
496 * @param mgr
497 * Client manager connection.
498 * @param msg
499 * Message to transmit, should be allocated with GNUNET_malloc() or
500 * GNUNET_new(), as it is freed with GNUNET_free() after transmission.
501 */
502void
503GNUNET_CLIENT_MANAGER_transmit (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
504 struct GNUNET_MessageHeader *msg)
505{
506 struct MessageQueueItem *mqi;
507
508 mqi = GNUNET_new (struct MessageQueueItem);
509 mqi->msg = GNUNET_copy_message (msg);
510 GNUNET_CONTAINER_DLL_insert_tail (mgr->tmit_head,
511 mgr->tmit_tail,
512 mqi);
513 transmit_next (mgr);
514}
515
516
517/**
518 * Add a message to the beginning of the transmission queue.
519 *
520 * @param mgr
521 * Client manager connection.
522 * @param msg
523 * Message to transmit, should be allocated with GNUNET_malloc() or
524 * GNUNET_new(), as it is freed with GNUNET_free() after transmission.
525 */
526void
527GNUNET_CLIENT_MANAGER_transmit_now (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
528 struct GNUNET_MessageHeader *msg)
529{
530 struct MessageQueueItem *mqi;
531
532 mqi = GNUNET_new (struct MessageQueueItem);
533 mqi->msg = GNUNET_copy_message (msg);
534 GNUNET_CONTAINER_DLL_insert (mgr->tmit_head,
535 mgr->tmit_tail,
536 mqi);
537 transmit_next (mgr);
538}
539
540
541/**
542 * Drop all queued messages.
543 *
544 * @param mgr
545 * Client manager connection.
546 */
547void
548GNUNET_CLIENT_MANAGER_drop_queue (struct GNUNET_CLIENT_MANAGER_Connection *mgr)
549{
550 struct MessageQueueItem *cur;
551 struct MessageQueueItem *next;
552
553 next = mgr->tmit_head;
554 while (NULL != next)
555 {
556 cur = next;
557 next = cur->next;
558 GNUNET_free (cur->msg);
559 GNUNET_free (cur);
560 }
561}
562
563
564/**
565 * Obtain client connection handle.
566 *
567 * @param mgr
568 * Client manager connection.
569 *
570 * @return Client connection handle.
571 */
572struct GNUNET_CLIENT_Connection *
573GNUNET_CLIENT_MANAGER_get_client (struct GNUNET_CLIENT_MANAGER_Connection *mgr)
574{
575 return mgr->client;
576}
577
578
579/**
580 * Return user context associated with the given client.
581 * Note: you should probably use the macro (call without the underscore).
582 *
583 * @param mgr
584 * Client manager connection.
585 * @param size
586 * Number of bytes in user context struct (for verification only).
587 *
588 * @return User context.
589 */
590void *
591GNUNET_CLIENT_MANAGER_get_user_context_ (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
592 size_t size)
593{
594 if ((0 == mgr->user_ctx_size) &&
595 (NULL == mgr->user_ctx))
596 return NULL; /* never set */
597 GNUNET_assert (size == mgr->user_ctx_size);
598 return mgr->user_ctx;
599}
600
601
602/**
603 * Set user context to be associated with the given client.
604 * Note: you should probably use the macro (call without the underscore).
605 *
606 * @param mgr
607 * Client manager connection.
608 * @param ctx
609 * User context.
610 * @param size
611 * Number of bytes in user context struct (for verification only).
612 */
613void
614GNUNET_CLIENT_MANAGER_set_user_context_ (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
615 void *ctx,
616 size_t size)
617{
618 if (NULL == ctx)
619 {
620 mgr->user_ctx_size = 0;
621 mgr->user_ctx = ctx;
622 return;
623 }
624 mgr->user_ctx_size = size;
625 mgr->user_ctx = ctx;
626}
627
628
629/**
630 * Get a unique operation ID to distinguish between asynchronous requests.
631 *
632 * @param mgr
633 * Client manager connection.
634 *
635 * @return Operation ID to use.
636 */
637uint64_t
638GNUNET_CLIENT_MANAGER_op_get_next_id (struct GNUNET_CLIENT_MANAGER_Connection *mgr)
639{
640 return ++mgr->last_op_id;
641}
642
643
644/**
645 * Find operation by ID.
646 *
647 * @param mgr
648 * Client manager connection.
649 * @param op_id
650 * Operation ID to look up.
651 *
652 * @return Operation, or NULL if not found.
653 */
654static struct OperationListItem *
655op_find (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
656 uint64_t op_id)
657{
658 struct OperationListItem *op;
659
660 for (op = mgr->op_head; NULL != op; op = op->next)
661 if (op->op_id == op_id)
662 return op;
663 return NULL;
664}
665
666
667/**
668 * Find operation by ID.
669 *
670 * @param mgr
671 * Client manager connection.
672 * @param op_id
673 * Operation ID to look up.
674 * @param[out] result_cb
675 * If an operation was found, its result callback is returned here.
676 * @param[out] cls
677 * If an operation was found, its closure is returned here.
678 *
679 * @return #GNUNET_YES if an operation was found,
680 * #GNUNET_NO if not found.
681 */
682int
683GNUNET_CLIENT_MANAGER_op_find (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
684 uint64_t op_id,
685 GNUNET_ResultCallback *result_cb,
686 void **cls)
687{
688 struct OperationListItem *op = op_find (mgr, op_id);
689 if (NULL != op)
690 {
691 *result_cb = op->result_cb;
692 *cls = op->cls;
693 return GNUNET_YES;
694 }
695 return GNUNET_NO;
696}
697
698
699/**
700 * Add a new operation.
701 *
702 * @param mgr
703 * Client manager connection.
704 * @param result_cb
705 * Function to call with the result of the operation.
706 * @param cls
707 * Closure for @a result_cb.
708 *
709 * @return ID of the new operation.
710 */
711uint64_t
712GNUNET_CLIENT_MANAGER_op_add (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
713 GNUNET_ResultCallback result_cb,
714 void *cls)
715{
716 struct OperationListItem *op;
717
718 if (NULL == result_cb)
719 return 0;
720 op = GNUNET_new (struct OperationListItem);
721 op->op_id = GNUNET_CLIENT_MANAGER_op_get_next_id (mgr);
722 op->result_cb = result_cb;
723 op->cls = cls;
724 GNUNET_CONTAINER_DLL_insert_tail (mgr->op_head,
725 mgr->op_tail,
726 op);
727 LOG (GNUNET_ERROR_TYPE_DEBUG,
728 "%p Added operation #%" PRIu64 "\n",
729 mgr,
730 op->op_id);
731 return op->op_id;
732}
733
734
735/**
736 * Remove an operation, and call its result callback (unless it was cancelled).
737 *
738 *
739 * @param mgr
740 * Client manager connection.
741 * @param op_id
742 * Operation ID.
743 * @param result_code
744 * Result of the operation.
745 * @param data
746 * Data result of the operation.
747 * @param data_size
748 * Size of @a data.
749 * @param cancel
750 * Is the operation cancelled?
751 * #GNUNET_NO Not cancelled, result callback is called.
752 * #GNUNET_YES Cancelled, result callback is not called.
753 *
754 * @return #GNUNET_YES if the operation was found and removed,
755 * #GNUNET_NO if the operation was not found.
756 */
757static int
758op_result (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
759 uint64_t op_id,
760 int64_t result_code,
761 const void *data,
762 uint16_t data_size,
763 uint8_t cancel)
764{
765 if (0 == op_id)
766 return GNUNET_NO;
767
768 struct OperationListItem *op = op_find (mgr, op_id);
769 if (NULL == op)
770 {
771 LOG (GNUNET_ERROR_TYPE_WARNING,
772 "Could not find operation #%" PRIu64 "\n", op_id);
773 return GNUNET_NO;
774 }
775
776 GNUNET_CONTAINER_DLL_remove (mgr->op_head,
777 mgr->op_tail,
778 op);
779
780 if ( (GNUNET_YES != cancel) &&
781 (NULL != op->result_cb) )
782 op->result_cb (op->cls,
783 result_code, data,
784 data_size);
785 GNUNET_free (op);
786 return GNUNET_YES;
787}
788
789
790/**
791 * Call the result callback of an operation and remove it.
792 *
793 * @param mgr
794 * Client manager connection.
795 * @param op_id
796 * Operation ID.
797 * @param result_code
798 * Result of the operation.
799 * @param data
800 * Data result of the operation.
801 * @param data_size
802 * Size of @a data.
803 *
804 * @return #GNUNET_YES if the operation was found and removed,
805 * #GNUNET_NO if the operation was not found.
806 */
807int
808GNUNET_CLIENT_MANAGER_op_result (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
809 uint64_t op_id,
810 int64_t result_code,
811 const void *data,
812 uint16_t data_size)
813{
814 LOG (GNUNET_ERROR_TYPE_DEBUG,
815 "%p Received result for operation #%" PRIu64 ": %" PRId64 " (size: %u)\n",
816 mgr, op_id, result_code, data_size);
817 return op_result (mgr, op_id, result_code, data, data_size, GNUNET_NO);
818}
819
820
821/**
822 * Cancel an operation.
823 *
824 * @param mgr
825 * Client manager connection.
826 * @param op_id
827 * Operation ID.
828 *
829 * @return #GNUNET_YES if the operation was found and removed,
830 * #GNUNET_NO if the operation was not found.
831 */
832int
833GNUNET_CLIENT_MANAGER_op_cancel (struct GNUNET_CLIENT_MANAGER_Connection *mgr,
834 uint64_t op_id)
835{
836 LOG (GNUNET_ERROR_TYPE_DEBUG,
837 "%p Cancelling operation #%" PRIu64 "\n",
838 mgr,
839 op_id);
840 return op_result (mgr, op_id, 0, NULL, 0, GNUNET_YES);
841}