aboutsummaryrefslogtreecommitdiff
path: root/src/set/set_api.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-11-27 13:55:23 +0000
committerChristian Grothoff <christian@grothoff.org>2014-11-27 13:55:23 +0000
commite98619f67a3e1ddf4962c20f77c7a1a669345eaa (patch)
tree50f3a427277571036043bde17e11f8b85fd2b4d6 /src/set/set_api.c
parent1d96a7f8dc2aa6311eae76e60a92eb2a2b397fe2 (diff)
downloadgnunet-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.c40
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 */
216static void 222static 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,
608void 621void
609GNUNET_SET_destroy (struct GNUNET_SET_Handle *set) 622GNUNET_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 */
951void
952GNUNET_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 */