diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-11-27 13:55:23 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-11-27 13:55:23 +0000 |
commit | e98619f67a3e1ddf4962c20f77c7a1a669345eaa (patch) | |
tree | 50f3a427277571036043bde17e11f8b85fd2b4d6 /src/set | |
parent | 1d96a7f8dc2aa6311eae76e60a92eb2a2b397fe2 (diff) | |
download | gnunet-e98619f67a3e1ddf4962c20f77c7a1a669345eaa.tar.gz gnunet-e98619f67a3e1ddf4962c20f77c7a1a669345eaa.zip |
adding logic to allow GNUNET_SET_iterate_cancel
Diffstat (limited to 'src/set')
-rw-r--r-- | src/set/gnunet-service-set.c | 4 | ||||
-rw-r--r-- | src/set/gnunet-service-set.h | 6 | ||||
-rw-r--r-- | src/set/set.h | 20 | ||||
-rw-r--r-- | src/set/set_api.c | 40 |
4 files changed, 61 insertions, 9 deletions
diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c index 5e1b89936..b2c3da7dc 100644 --- a/src/set/gnunet-service-set.c +++ b/src/set/gnunet-service-set.c | |||
@@ -410,6 +410,7 @@ set_destroy (struct Set *set) | |||
410 | { | 410 | { |
411 | GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter); | 411 | GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter); |
412 | set->iter = NULL; | 412 | set->iter = NULL; |
413 | set->iteration_id++; | ||
413 | } | 414 | } |
414 | if (NULL != set->elements) | 415 | if (NULL != set->elements) |
415 | { | 416 | { |
@@ -667,6 +668,7 @@ send_client_element (struct Set *set) | |||
667 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_ITER_DONE); | 668 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_ITER_DONE); |
668 | GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter); | 669 | GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter); |
669 | set->iter = NULL; | 670 | set->iter = NULL; |
671 | set->iteration_id++; | ||
670 | } | 672 | } |
671 | else | 673 | else |
672 | { | 674 | { |
@@ -678,6 +680,7 @@ send_client_element (struct Set *set) | |||
678 | ee->element.data, | 680 | ee->element.data, |
679 | ee->element.size); | 681 | ee->element.size); |
680 | msg->element_type = ee->element.element_type; | 682 | msg->element_type = ee->element.element_type; |
683 | msg->iteration_id = htons (set->iteration_id); | ||
681 | } | 684 | } |
682 | GNUNET_MQ_send (set->client_mq, ev); | 685 | GNUNET_MQ_send (set->client_mq, ev); |
683 | } | 686 | } |
@@ -1097,6 +1100,7 @@ handle_client_iter_ack (void *cls, | |||
1097 | { | 1100 | { |
1098 | GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter); | 1101 | GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter); |
1099 | set->iter = NULL; | 1102 | set->iter = NULL; |
1103 | set->iteration_id++; | ||
1100 | } | 1104 | } |
1101 | } | 1105 | } |
1102 | 1106 | ||
diff --git a/src/set/gnunet-service-set.h b/src/set/gnunet-service-set.h index 448ed9478..ab8155883 100644 --- a/src/set/gnunet-service-set.h +++ b/src/set/gnunet-service-set.h | |||
@@ -468,6 +468,12 @@ struct Set | |||
468 | */ | 468 | */ |
469 | enum GNUNET_SET_OperationType operation; | 469 | enum GNUNET_SET_OperationType operation; |
470 | 470 | ||
471 | /** | ||
472 | * Each @e iter is assigned a unique number, so that the client | ||
473 | * can distinguish iterations. | ||
474 | */ | ||
475 | uint16_t iteration_id; | ||
476 | |||
471 | }; | 477 | }; |
472 | 478 | ||
473 | 479 | ||
diff --git a/src/set/set.h b/src/set/set.h index 01c96896d..944881b63 100644 --- a/src/set/set.h +++ b/src/set/set.h | |||
@@ -29,12 +29,6 @@ | |||
29 | #include "platform.h" | 29 | #include "platform.h" |
30 | #include "gnunet_common.h" | 30 | #include "gnunet_common.h" |
31 | 31 | ||
32 | /** | ||
33 | * FIXME | ||
34 | */ | ||
35 | #define GNUNET_SET_ACK_WINDOW 10 | ||
36 | |||
37 | |||
38 | GNUNET_NETWORK_STRUCT_BEGIN | 32 | GNUNET_NETWORK_STRUCT_BEGIN |
39 | 33 | ||
40 | /** | 34 | /** |
@@ -266,6 +260,10 @@ struct GNUNET_SET_CancelMessage | |||
266 | }; | 260 | }; |
267 | 261 | ||
268 | 262 | ||
263 | /** | ||
264 | * Set element transmitted by service to client in response to a set | ||
265 | * iteration request. | ||
266 | */ | ||
269 | struct GNUNET_SET_IterResponseMessage | 267 | struct GNUNET_SET_IterResponseMessage |
270 | { | 268 | { |
271 | /** | 269 | /** |
@@ -274,6 +272,12 @@ struct GNUNET_SET_IterResponseMessage | |||
274 | struct GNUNET_MessageHeader header; | 272 | struct GNUNET_MessageHeader header; |
275 | 273 | ||
276 | /** | 274 | /** |
275 | * To which set iteration does this reponse belong to? First | ||
276 | * iteration (per client) has counter zero. Wraps around. | ||
277 | */ | ||
278 | uint16_t iteration_id GNUNET_PACKED; | ||
279 | |||
280 | /** | ||
277 | * Type of the element attachted to the message, | 281 | * Type of the element attachted to the message, |
278 | * if any. | 282 | * if any. |
279 | */ | 283 | */ |
@@ -282,6 +286,10 @@ struct GNUNET_SET_IterResponseMessage | |||
282 | /* rest: element */ | 286 | /* rest: element */ |
283 | }; | 287 | }; |
284 | 288 | ||
289 | |||
290 | /** | ||
291 | * Client acknowledges receiving element in iteration. | ||
292 | */ | ||
285 | struct GNUNET_SET_IterAckMessage | 293 | struct GNUNET_SET_IterAckMessage |
286 | { | 294 | { |
287 | /** | 295 | /** |
diff --git a/src/set/set_api.c b/src/set/set_api.c index d62475013..b919f6e02 100644 --- a/src/set/set_api.c +++ b/src/set/set_api.c | |||
@@ -77,6 +77,12 @@ struct GNUNET_SET_Handle | |||
77 | * Has the set become invalid (e.g. service died)? | 77 | * Has the set become invalid (e.g. service died)? |
78 | */ | 78 | */ |
79 | int invalid; | 79 | int invalid; |
80 | |||
81 | /** | ||
82 | * Both client and service count the number of iterators | ||
83 | * created so far to match replies with iterators. | ||
84 | */ | ||
85 | uint16_t iteration_id; | ||
80 | }; | 86 | }; |
81 | 87 | ||
82 | 88 | ||
@@ -210,7 +216,7 @@ struct GNUNET_SET_ListenHandle | |||
210 | * Handle element for iteration over the set. Notifies the | 216 | * Handle element for iteration over the set. Notifies the |
211 | * iterator and sends an acknowledgement to the service. | 217 | * iterator and sends an acknowledgement to the service. |
212 | * | 218 | * |
213 | * @param cls the set | 219 | * @param cls the `struct GNUNET_SET_Handle *` |
214 | * @param mh the message | 220 | * @param mh the message |
215 | */ | 221 | */ |
216 | static void | 222 | static void |
@@ -231,13 +237,19 @@ handle_iter_element (void *cls, | |||
231 | /* message malformed */ | 237 | /* message malformed */ |
232 | GNUNET_break (0); | 238 | GNUNET_break (0); |
233 | set->iterator = NULL; | 239 | set->iterator = NULL; |
240 | set->iteration_id++; | ||
234 | iter (set->iterator_cls, | 241 | iter (set->iterator_cls, |
235 | NULL); | 242 | NULL); |
236 | iter = NULL; | 243 | iter = NULL; |
237 | } | 244 | } |
245 | msg = (const struct GNUNET_SET_IterResponseMessage *) mh; | ||
246 | if (set->iteration_id != ntohs (msg->iteration_id)) | ||
247 | { | ||
248 | /* element from a previous iteration, skip! */ | ||
249 | iter = NULL; | ||
250 | } | ||
238 | if (NULL != iter) | 251 | if (NULL != iter) |
239 | { | 252 | { |
240 | msg = (const struct GNUNET_SET_IterResponseMessage *) mh; | ||
241 | element.size = msize - sizeof (struct GNUNET_SET_IterResponseMessage); | 253 | element.size = msize - sizeof (struct GNUNET_SET_IterResponseMessage); |
242 | element.element_type = htons (msg->element_type); | 254 | element.element_type = htons (msg->element_type); |
243 | element.data = &msg[1]; | 255 | element.data = &msg[1]; |
@@ -268,6 +280,7 @@ handle_iter_done (void *cls, | |||
268 | if (NULL == iter) | 280 | if (NULL == iter) |
269 | return; | 281 | return; |
270 | set->iterator = NULL; | 282 | set->iterator = NULL; |
283 | set->iteration_id++; | ||
271 | iter (set->iterator_cls, | 284 | iter (set->iterator_cls, |
272 | NULL); | 285 | NULL); |
273 | } | 286 | } |
@@ -304,7 +317,7 @@ handle_result (void *cls, | |||
304 | } | 317 | } |
305 | if (GNUNET_SET_STATUS_OK != result_status) | 318 | if (GNUNET_SET_STATUS_OK != result_status) |
306 | { | 319 | { |
307 | /* status is not STATUS_OK => there's no attached element, | 320 | /* status is not #GNUNET_SET_STATUS_OK => there's no attached element, |
308 | * and this is the last result message we get */ | 321 | * and this is the last result message we get */ |
309 | GNUNET_MQ_assoc_remove (set->mq, ntohl (msg->request_id)); | 322 | GNUNET_MQ_assoc_remove (set->mq, ntohl (msg->request_id)); |
310 | GNUNET_CONTAINER_DLL_remove (set->ops_head, | 323 | GNUNET_CONTAINER_DLL_remove (set->ops_head, |
@@ -608,6 +621,10 @@ GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set, | |||
608 | void | 621 | void |
609 | GNUNET_SET_destroy (struct GNUNET_SET_Handle *set) | 622 | GNUNET_SET_destroy (struct GNUNET_SET_Handle *set) |
610 | { | 623 | { |
624 | /* destroying set while iterator is active is currently | ||
625 | not supported; we should expand the API to allow | ||
626 | clients to explicitly cancel the iteration! */ | ||
627 | GNUNET_assert (NULL == set->iterator); | ||
611 | if (NULL != set->ops_head) | 628 | if (NULL != set->ops_head) |
612 | { | 629 | { |
613 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 630 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -923,4 +940,21 @@ GNUNET_SET_iterate (struct GNUNET_SET_Handle *set, | |||
923 | return GNUNET_YES; | 940 | return GNUNET_YES; |
924 | } | 941 | } |
925 | 942 | ||
943 | |||
944 | /** | ||
945 | * Stop iteration over all elements in the given set. Can only | ||
946 | * be called before the iteration has "naturally" completed its | ||
947 | * turn. | ||
948 | * | ||
949 | * @param set the set to stop iterating over | ||
950 | */ | ||
951 | void | ||
952 | GNUNET_SET_iterate_cancel (struct GNUNET_SET_Handle *set) | ||
953 | { | ||
954 | GNUNET_assert (NULL != set->iterator); | ||
955 | set->iterator = NULL; | ||
956 | set->iteration_id++; | ||
957 | } | ||
958 | |||
959 | |||
926 | /* end of set_api.c */ | 960 | /* end of set_api.c */ |