aboutsummaryrefslogtreecommitdiff
path: root/src/set
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
parent1d96a7f8dc2aa6311eae76e60a92eb2a2b397fe2 (diff)
downloadgnunet-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.c4
-rw-r--r--src/set/gnunet-service-set.h6
-rw-r--r--src/set/set.h20
-rw-r--r--src/set/set_api.c40
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
38GNUNET_NETWORK_STRUCT_BEGIN 32GNUNET_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 */
269struct GNUNET_SET_IterResponseMessage 267struct 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 */
285struct GNUNET_SET_IterAckMessage 293struct 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 */
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 */