From 2e482e23a8d51f58e6ff80782e360cf9f47e174c Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 15 Jan 2010 10:07:33 +0000 Subject: [PATCH] allow cancellation of peerinfo iterations --- src/include/gnunet_peerinfo_service.h | 33 +++++++++++++++----- src/peerinfo/gnunet-peerinfo.c | 14 ++++----- src/peerinfo/peerinfo_api.c | 44 ++++++++++++++++++--------- 3 files changed, 62 insertions(+), 29 deletions(-) diff --git a/src/include/gnunet_peerinfo_service.h b/src/include/gnunet_peerinfo_service.h index 463131e6a..6deed04d9 100644 --- a/src/include/gnunet_peerinfo_service.h +++ b/src/include/gnunet_peerinfo_service.h @@ -72,14 +72,22 @@ typedef void uint32_t trust); +/** + * Handle for cancellation of iteration over peers. + */ +struct GNUNET_PEERINFO_IteratorContext; + + /** * Call a method for each known matching host and change * its trust value. The method will be invoked once for - * each host and then finally once with a NULL pointer. - * Note that the last call can be triggered by timeout or - * by simply being done; however, the trust argument will - * be set to zero if we are done, 1 if we timed out and - * 2 for fatal error. + * each host and then finally once with a NULL pointer. After + * that final invocation, the iterator context must no longer + * be used. + * + * Note that the last call can be triggered by timeout or by simply + * being done; however, the trust argument will be set to zero if we + * are done, 1 if we timed out and 2 for fatal error. * * @param cfg configuration to use * @param sched scheduler to use @@ -88,9 +96,11 @@ typedef void * @param timeout how long to wait until timing out * @param callback the method to call for each peer * @param callback_cls closure for callback + * @return NULL on error (in this case, 'callback' is never called!), + * otherwise an iterator context */ -void -GNUNET_PEERINFO_for_all (const struct GNUNET_CONFIGURATION_Handle *cfg, +struct GNUNET_PEERINFO_IteratorContext * +GNUNET_PEERINFO_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SCHEDULER_Handle *sched, const struct GNUNET_PeerIdentity *peer, int trust_delta, @@ -99,6 +109,15 @@ GNUNET_PEERINFO_for_all (const struct GNUNET_CONFIGURATION_Handle *cfg, void *callback_cls); +/** + * Cancel an iteration over peer information. + * + * @param ic context of the iterator to cancel + */ +void +GNUNET_PEERINFO_iterate_cancel (struct GNUNET_PEERINFO_IteratorContext *ic); + + /** * Handle for notifications about changes to the set of known peers. */ diff --git a/src/peerinfo/gnunet-peerinfo.c b/src/peerinfo/gnunet-peerinfo.c index 931673ed9..8c469dad9 100644 --- a/src/peerinfo/gnunet-peerinfo.c +++ b/src/peerinfo/gnunet-peerinfo.c @@ -85,13 +85,13 @@ run (void *cls, if (get_self != GNUNET_YES) { - GNUNET_PEERINFO_for_all (cfg, - sched, - NULL, - 0, - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 30), - &print_peer_info, NULL); + (void) GNUNET_PEERINFO_iterate (cfg, + sched, + NULL, + 0, + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 30), + &print_peer_info, NULL); } else { diff --git a/src/peerinfo/peerinfo_api.c b/src/peerinfo/peerinfo_api.c index 906c01d77..3ed2172db 100644 --- a/src/peerinfo/peerinfo_api.c +++ b/src/peerinfo/peerinfo_api.c @@ -120,7 +120,7 @@ GNUNET_PEERINFO_add_peer (const struct GNUNET_CONFIGURATION_Handle *cfg, /** * Context for the info handler. */ -struct InfoContext +struct GNUNET_PEERINFO_IteratorContext { /** @@ -156,7 +156,7 @@ struct InfoContext static void info_handler (void *cls, const struct GNUNET_MessageHeader *msg) { - struct InfoContext *ic = cls; + struct GNUNET_PEERINFO_IteratorContext *ic = cls; const struct InfoMessage *im; const struct GNUNET_HELLO_Message *hello; uint16_t ms; @@ -234,9 +234,10 @@ info_handler (void *cls, const struct GNUNET_MessageHeader *msg) * @param timeout how long to wait until timing out * @param callback the method to call for each peer * @param callback_cls closure for callback + * @return NULL on error, otherwise an iterator context */ -void -GNUNET_PEERINFO_for_all (const struct GNUNET_CONFIGURATION_Handle *cfg, +struct GNUNET_PEERINFO_IteratorContext * +GNUNET_PEERINFO_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SCHEDULER_Handle *sched, const struct GNUNET_PeerIdentity *peer, int trust_delta, @@ -247,28 +248,23 @@ GNUNET_PEERINFO_for_all (const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_CLIENT_Connection *client; struct ListAllPeersMessage *lapm; struct ListPeerMessage *lpm; - struct InfoContext *ihc; + struct GNUNET_PEERINFO_IteratorContext *ihc; client = GNUNET_CLIENT_connect (sched, "peerinfo", cfg); if (client == NULL) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Could not connect to `%s' service.\n"), "peerinfo"); - callback (callback_cls, NULL, NULL, 2); - return; + return NULL; } #if DEBUG_PEERINFO GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting list of peers from peerinfo database\n"); #endif - ihc = GNUNET_malloc (sizeof (struct InfoContext) + - sizeof (struct ListPeerMessage)); - ihc->client = client; - ihc->callback = callback; - ihc->callback_cls = callback_cls; - ihc->timeout = GNUNET_TIME_relative_to_absolute (timeout); if (peer == NULL) { + ihc = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_IteratorContext) + + sizeof (struct ListAllPeersMessage)); lapm = (struct ListAllPeersMessage *) &ihc[1]; lapm->header.size = htons (sizeof (struct ListAllPeersMessage)); lapm->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL); @@ -276,12 +272,18 @@ GNUNET_PEERINFO_for_all (const struct GNUNET_CONFIGURATION_Handle *cfg, } else { + ihc = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_IteratorContext) + + sizeof (struct ListPeerMessage)); lpm = (struct ListPeerMessage *) &ihc[1]; lpm->header.size = htons (sizeof (struct ListPeerMessage)); lpm->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET); lpm->trust_change = htonl (trust_delta); memcpy (&lpm->peer, peer, sizeof (struct GNUNET_PeerIdentity)); } + ihc->client = client; + ihc->callback = callback; + ihc->callback_cls = callback_cls; + ihc->timeout = GNUNET_TIME_relative_to_absolute (timeout); if (GNUNET_OK != GNUNET_CLIENT_transmit_and_get_response (client, (const struct GNUNET_MessageHeader*) &ihc[1], @@ -291,14 +293,26 @@ GNUNET_PEERINFO_for_all (const struct GNUNET_CONFIGURATION_Handle *cfg, ihc)) { GNUNET_break (0); - ihc->callback (ihc->callback_cls, NULL, NULL, 1); GNUNET_CLIENT_disconnect (ihc->client); GNUNET_free (ihc); - return; + return NULL; } + return ihc; } +/** + * Cancel an iteration over peer information. + * + * @param ic context of the iterator to cancel + */ +void +GNUNET_PEERINFO_iterate_cancel (struct GNUNET_PEERINFO_IteratorContext *ic) +{ + GNUNET_CLIENT_disconnect (ic->client); + GNUNET_free (ic); +} + /** * Context for the info handler. -- 2.25.1