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/set_api.c | |
parent | 1d96a7f8dc2aa6311eae76e60a92eb2a2b397fe2 (diff) | |
download | gnunet-e98619f67a3e1ddf4962c20f77c7a1a669345eaa.tar.gz gnunet-e98619f67a3e1ddf4962c20f77c7a1a669345eaa.zip |
adding logic to allow GNUNET_SET_iterate_cancel
Diffstat (limited to 'src/set/set_api.c')
-rw-r--r-- | src/set/set_api.c | 40 |
1 files changed, 37 insertions, 3 deletions
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 */ |