aboutsummaryrefslogtreecommitdiff
path: root/src/peerstore/peerstore_api.c
diff options
context:
space:
mode:
authorOmar Tarabai <tarabai@devegypt.com>2014-07-09 14:46:56 +0000
committerOmar Tarabai <tarabai@devegypt.com>2014-07-09 14:46:56 +0000
commite5d7c67c647e9620c5c1ae77e133a74698443ee1 (patch)
tree1f49323d5963cc4a77e2648b29744ad5cf6291bf /src/peerstore/peerstore_api.c
parent696df0a02abec9683b34c3097cff4448ad154367 (diff)
downloadgnunet-e5d7c67c647e9620c5c1ae77e133a74698443ee1.tar.gz
gnunet-e5d7c67c647e9620c5c1ae77e133a74698443ee1.zip
Added flag to API disconnect method to send pending store requests before disconnecting.
Added a test case for it.
Diffstat (limited to 'src/peerstore/peerstore_api.c')
-rw-r--r--src/peerstore/peerstore_api.c121
1 files changed, 98 insertions, 23 deletions
diff --git a/src/peerstore/peerstore_api.c b/src/peerstore/peerstore_api.c
index b13b0136c..81d287b53 100644
--- a/src/peerstore/peerstore_api.c
+++ b/src/peerstore/peerstore_api.c
@@ -80,6 +80,11 @@ struct GNUNET_PEERSTORE_Handle
80 */ 80 */
81 struct GNUNET_CONTAINER_MultiHashMap *watches; 81 struct GNUNET_CONTAINER_MultiHashMap *watches;
82 82
83 /**
84 * Are we in the process of disconnecting but need to sync first?
85 */
86 int disconnecting;
87
83}; 88};
84 89
85/** 90/**
@@ -226,7 +231,8 @@ struct GNUNET_PEERSTORE_WatchContext
226 * @param cls a 'struct GNUNET_PEERSTORE_Handle *' 231 * @param cls a 'struct GNUNET_PEERSTORE_Handle *'
227 * @param msg message received, NULL on timeout or fatal error 232 * @param msg message received, NULL on timeout or fatal error
228 */ 233 */
229void handle_iterate_result (void *cls, const struct GNUNET_MessageHeader *msg); 234static void
235handle_iterate_result (void *cls, const struct GNUNET_MessageHeader *msg);
230 236
231/** 237/**
232 * When a watch record is received 238 * When a watch record is received
@@ -234,7 +240,8 @@ void handle_iterate_result (void *cls, const struct GNUNET_MessageHeader *msg);
234 * @param cls a 'struct GNUNET_PEERSTORE_Handle *' 240 * @param cls a 'struct GNUNET_PEERSTORE_Handle *'
235 * @param msg message received, NULL on timeout or fatal error 241 * @param msg message received, NULL on timeout or fatal error
236 */ 242 */
237void handle_watch_result (void *cls, const struct GNUNET_MessageHeader *msg); 243static void
244handle_watch_result (void *cls, const struct GNUNET_MessageHeader *msg);
238 245
239/** 246/**
240 * Close the existing connection to PEERSTORE and reconnect. 247 * Close the existing connection to PEERSTORE and reconnect.
@@ -249,21 +256,21 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h);
249 * 256 *
250 * @param cls a 'struct GNUNET_PEERSTORE_WatchContext *' 257 * @param cls a 'struct GNUNET_PEERSTORE_WatchContext *'
251 */ 258 */
252void watch_request_sent (void *cls); 259static void watch_request_sent (void *cls);
253 260
254/** 261/**
255 * Callback after MQ envelope is sent 262 * Callback after MQ envelope is sent
256 * 263 *
257 * @param cls a 'struct GNUNET_PEERSTORE_IterateContext *' 264 * @param cls a 'struct GNUNET_PEERSTORE_IterateContext *'
258 */ 265 */
259void iterate_request_sent (void *cls); 266static void iterate_request_sent (void *cls);
260 267
261/** 268/**
262 * Callback after MQ envelope is sent 269 * Callback after MQ envelope is sent
263 * 270 *
264 * @param cls a 'struct GNUNET_PEERSTORE_StoreContext *' 271 * @param cls a 'struct GNUNET_PEERSTORE_StoreContext *'
265 */ 272 */
266void store_request_sent (void *cls); 273static void store_request_sent (void *cls);
267 274
268/** 275/**
269 * MQ message handlers 276 * MQ message handlers
@@ -291,7 +298,7 @@ handle_client_error (void *cls, enum GNUNET_MQ_Error error)
291/** 298/**
292 * Iterator over previous watches to resend them 299 * Iterator over previous watches to resend them
293 */ 300 */
294int rewatch_it(void *cls, 301static int rewatch_it(void *cls,
295 const struct GNUNET_HashCode *key, 302 const struct GNUNET_HashCode *key,
296 void *value) 303 void *value)
297{ 304{
@@ -375,6 +382,45 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h)
375} 382}
376 383
377/** 384/**
385 * Iterator over watch requests to cancel them.
386 *
387 * @param cls unsused
388 * @param key key to the watch request
389 * @param value watch context
390 * @return #GNUNET_YES to continue iteration
391 */
392static int
393destroy_watch (void *cls, const struct GNUNET_HashCode *key, void *value)
394{
395 struct GNUNET_PEERSTORE_WatchContext *wc = value;
396
397 GNUNET_PEERSTORE_watch_cancel (wc);
398 return GNUNET_YES;
399}
400
401/**
402 * Kill the connection to the service. This can be delayed in case of pending
403 * STORE requests and the user explicitly asked to sync first. Otherwise it is
404 * performed instantly.
405 *
406 * @param h Handle to the service.
407 */
408static void do_disconnect (struct GNUNET_PEERSTORE_Handle *h)
409{
410 if(NULL != h->mq)
411 {
412 GNUNET_MQ_destroy(h->mq);
413 h->mq = NULL;
414 }
415 if (NULL != h->client)
416 {
417 GNUNET_CLIENT_disconnect (h->client);
418 h->client = NULL;
419 }
420 GNUNET_free(h);
421}
422
423/**
378 * Connect to the PEERSTORE service. 424 * Connect to the PEERSTORE service.
379 * 425 *
380 * @return NULL on error 426 * @return NULL on error
@@ -392,6 +438,7 @@ GNUNET_PEERSTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
392 return NULL; 438 return NULL;
393 } 439 }
394 h->cfg = cfg; 440 h->cfg = cfg;
441 h->disconnecting = GNUNET_NO;
395 h->mq = GNUNET_MQ_queue_for_connection_client(h->client, 442 h->mq = GNUNET_MQ_queue_for_connection_client(h->client,
396 mq_handlers, 443 mq_handlers,
397 &handle_client_error, 444 &handle_client_error,
@@ -406,32 +453,52 @@ GNUNET_PEERSTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
406} 453}
407 454
408/** 455/**
409 * Disconnect from the PEERSTORE service 456 * Disconnect from the PEERSTORE service. Any pending ITERATE and WATCH requests
410 * Do not call in case of pending requests 457 * will be canceled. Any pending STORE requests will depend on @snyc_first flag.
411 * 458 *
412 * @param h handle to disconnect 459 * @param h handle to disconnect
460 * @param sync_first send any pending STORE requests before disconnecting
413 */ 461 */
414void 462void
415GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h) 463GNUNET_PEERSTORE_disconnect (struct GNUNET_PEERSTORE_Handle *h, int sync_first)
416{ 464{
465 struct GNUNET_PEERSTORE_IterateContext *ic;
466 struct GNUNET_PEERSTORE_IterateContext *ic_iter;
467 struct GNUNET_PEERSTORE_StoreContext *sc;
468 struct GNUNET_PEERSTORE_StoreContext *sc_iter;
469
417 LOG(GNUNET_ERROR_TYPE_DEBUG, "Disconnecting.\n"); 470 LOG(GNUNET_ERROR_TYPE_DEBUG, "Disconnecting.\n");
418 if(NULL != h->watches) 471 if(NULL != h->watches)
419 { 472 {
473 GNUNET_CONTAINER_multihashmap_iterate (h->watches, &destroy_watch, NULL);
420 GNUNET_CONTAINER_multihashmap_destroy(h->watches); 474 GNUNET_CONTAINER_multihashmap_destroy(h->watches);
421 h->watches = NULL; 475 h->watches = NULL;
422 } 476 }
423 if(NULL != h->mq) 477 ic_iter = h->iterate_head;
478 while (NULL != ic_iter)
424 { 479 {
425 GNUNET_MQ_destroy(h->mq); 480 ic = ic_iter;
426 h->mq = NULL; 481 ic_iter = ic_iter->next;
482 GNUNET_PEERSTORE_iterate_cancel (ic);
427 } 483 }
428 if (NULL != h->client) 484 if (NULL != h->store_head)
429 { 485 {
430 GNUNET_CLIENT_disconnect (h->client); 486 if (GNUNET_YES == sync_first)
431 h->client = NULL; 487 {
488 LOG (GNUNET_ERROR_TYPE_DEBUG,
489 "Delaying disconnection due to pending store requests.\n");
490 h->disconnecting = GNUNET_YES;
491 return;
492 }
493 sc_iter = h->store_head;
494 while (NULL != sc_iter)
495 {
496 sc = sc_iter;
497 sc_iter = sc_iter->next;
498 GNUNET_PEERSTORE_store_cancel (sc);
499 }
432 } 500 }
433 GNUNET_free(h); 501 do_disconnect (h);
434 LOG(GNUNET_ERROR_TYPE_DEBUG, "Disconnected, BYE!\n");
435} 502}
436 503
437 504
@@ -444,7 +511,7 @@ GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h)
444 * 511 *
445 * @param cls a 'struct GNUNET_PEERSTORE_StoreContext *' 512 * @param cls a 'struct GNUNET_PEERSTORE_StoreContext *'
446 */ 513 */
447void store_request_sent (void *cls) 514static void store_request_sent (void *cls)
448{ 515{
449 struct GNUNET_PEERSTORE_StoreContext *sc = cls; 516 struct GNUNET_PEERSTORE_StoreContext *sc = cls;
450 GNUNET_PEERSTORE_Continuation cont; 517 GNUNET_PEERSTORE_Continuation cont;
@@ -466,6 +533,8 @@ void store_request_sent (void *cls)
466void 533void
467GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext *sc) 534GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext *sc)
468{ 535{
536 struct GNUNET_PEERSTORE_Handle *h = sc->h;
537
469 if(NULL != sc->ev) 538 if(NULL != sc->ev)
470 { 539 {
471 GNUNET_MQ_send_cancel(sc->ev); 540 GNUNET_MQ_send_cancel(sc->ev);
@@ -473,6 +542,8 @@ GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext *sc)
473 } 542 }
474 GNUNET_CONTAINER_DLL_remove(sc->h->store_head, sc->h->store_tail, sc); 543 GNUNET_CONTAINER_DLL_remove(sc->h->store_head, sc->h->store_tail, sc);
475 GNUNET_free(sc); 544 GNUNET_free(sc);
545 if (GNUNET_YES == h->disconnecting && NULL == h->store_head)
546 do_disconnect (h);
476} 547}
477 548
478/** 549/**
@@ -538,7 +609,8 @@ GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
538 * @param cls a 'struct GNUNET_PEERSTORE_Handle *' 609 * @param cls a 'struct GNUNET_PEERSTORE_Handle *'
539 * @param msg message received, NULL on timeout or fatal error 610 * @param msg message received, NULL on timeout or fatal error
540 */ 611 */
541void handle_iterate_result (void *cls, const struct GNUNET_MessageHeader *msg) 612static void
613handle_iterate_result (void *cls, const struct GNUNET_MessageHeader *msg)
542{ 614{
543 struct GNUNET_PEERSTORE_Handle *h = cls; 615 struct GNUNET_PEERSTORE_Handle *h = cls;
544 struct GNUNET_PEERSTORE_IterateContext *ic; 616 struct GNUNET_PEERSTORE_IterateContext *ic;
@@ -596,7 +668,7 @@ void handle_iterate_result (void *cls, const struct GNUNET_MessageHeader *msg)
596 * 668 *
597 * @param cls a 'struct GNUNET_PEERSTORE_IterateContext *' 669 * @param cls a 'struct GNUNET_PEERSTORE_IterateContext *'
598 */ 670 */
599void iterate_request_sent (void *cls) 671static void iterate_request_sent (void *cls)
600{ 672{
601 struct GNUNET_PEERSTORE_IterateContext *ic = cls; 673 struct GNUNET_PEERSTORE_IterateContext *ic = cls;
602 674
@@ -610,7 +682,8 @@ void iterate_request_sent (void *cls)
610 * 682 *
611 * @param cls a 'struct GNUNET_PEERSTORE_IterateContext *' 683 * @param cls a 'struct GNUNET_PEERSTORE_IterateContext *'
612 */ 684 */
613void iterate_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 685static void
686iterate_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
614{ 687{
615 struct GNUNET_PEERSTORE_IterateContext *ic = cls; 688 struct GNUNET_PEERSTORE_IterateContext *ic = cls;
616 689
@@ -702,7 +775,8 @@ GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h,
702 * @param cls a 'struct GNUNET_PEERSTORE_Handle *' 775 * @param cls a 'struct GNUNET_PEERSTORE_Handle *'
703 * @param msg message received, NULL on timeout or fatal error 776 * @param msg message received, NULL on timeout or fatal error
704 */ 777 */
705void handle_watch_result (void *cls, const struct GNUNET_MessageHeader *msg) 778static void
779handle_watch_result (void *cls, const struct GNUNET_MessageHeader *msg)
706{ 780{
707 struct GNUNET_PEERSTORE_Handle *h = cls; 781 struct GNUNET_PEERSTORE_Handle *h = cls;
708 struct GNUNET_PEERSTORE_Record *record; 782 struct GNUNET_PEERSTORE_Record *record;
@@ -738,7 +812,7 @@ void handle_watch_result (void *cls, const struct GNUNET_MessageHeader *msg)
738 * 812 *
739 * @param cls a 'struct GNUNET_PEERSTORE_WatchContext *' 813 * @param cls a 'struct GNUNET_PEERSTORE_WatchContext *'
740 */ 814 */
741void watch_request_sent (void *cls) 815static void watch_request_sent (void *cls)
742{ 816{
743 struct GNUNET_PEERSTORE_WatchContext *wc = cls; 817 struct GNUNET_PEERSTORE_WatchContext *wc = cls;
744 818
@@ -762,6 +836,7 @@ GNUNET_PEERSTORE_watch_cancel(struct GNUNET_PEERSTORE_WatchContext *wc)
762 if(GNUNET_YES == wc->request_sent) /* If request already sent to service, send a cancel request. */ 836 if(GNUNET_YES == wc->request_sent) /* If request already sent to service, send a cancel request. */
763 { 837 {
764 ev = GNUNET_MQ_msg(hm, GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH_CANCEL); 838 ev = GNUNET_MQ_msg(hm, GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH_CANCEL);
839 hm->keyhash = wc->keyhash;
765 GNUNET_MQ_send(h->mq, ev); 840 GNUNET_MQ_send(h->mq, ev);
766 wc->callback = NULL; 841 wc->callback = NULL;
767 wc->callback_cls = NULL; 842 wc->callback_cls = NULL;