allow cancellation of peerinfo iterations
authorChristian Grothoff <christian@grothoff.org>
Fri, 15 Jan 2010 10:07:33 +0000 (10:07 +0000)
committerChristian Grothoff <christian@grothoff.org>
Fri, 15 Jan 2010 10:07:33 +0000 (10:07 +0000)
src/include/gnunet_peerinfo_service.h
src/peerinfo/gnunet-peerinfo.c
src/peerinfo/peerinfo_api.c

index 463131e6a81b7b3bcd97f4af4e816de6f2c20478..6deed04d97fd122dba1122deb057bd441c3e4926 100644 (file)
@@ -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.
  */
index 931673ed979f0f4afb330210d995dfa448c538f9..8c469dad9e688cf6259a8cfa63b1c5a63288aa5e 100644 (file)
@@ -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
     {
index 906c01d77287fa5d9fe5cd2c9f16a7d2eadad61e..3ed2172db358c33058b685772509500da574d9d5 100644 (file)
@@ -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.