implement watch_cancel function
authorChristian Grothoff <christian@grothoff.org>
Mon, 19 Dec 2011 21:26:34 +0000 (21:26 +0000)
committerChristian Grothoff <christian@grothoff.org>
Mon, 19 Dec 2011 21:26:34 +0000 (21:26 +0000)
src/include/gnunet_statistics_service.h
src/statistics/statistics_api.c

index 11796d7815cc1ce271521a750106676cd52353f6..bfd65f883511a12625e385814ec6c6e10b39db31 100644 (file)
@@ -91,8 +91,6 @@ GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h, int sync_first);
 
 /**
  * Watch statistics from the peer (be notified whenever they change).
- * Note that the only way to cancel a "watch" request is to destroy
- * the statistics handle given as the first argument to this call.
  *
  * @param handle identification of the statistics service
  * @param subsystem limit to the specified subsystem, never NULL
@@ -107,6 +105,22 @@ GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle,
                          GNUNET_STATISTICS_Iterator proc, void *proc_cls);
 
 
+/**
+ * Stop watching statistics from the peer.
+ *
+ * @param handle identification of the statistics service
+ * @param subsystem limit to the specified subsystem, never NULL
+ * @param name name of the statistic value, never NULL
+ * @param proc function to call on each value
+ * @param proc_cls closure for proc
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error (no such watch)
+ */
+int
+GNUNET_STATISTICS_watch_cancel (struct GNUNET_STATISTICS_Handle *handle,
+                               const char *subsystem, const char *name,
+                               GNUNET_STATISTICS_Iterator proc, void *proc_cls);
+
+
 /**
  * Continuation called by the "get_all" and "get" functions.
  *
@@ -116,6 +130,7 @@ GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle,
  */
 typedef void (*GNUNET_STATISTICS_Callback) (void *cls, int success);
 
+
 /**
  * Handle that can be used to cancel a statistics 'get' operation.
  */
index 8335e9e0c9d69fb4591f2c7234dad9215e799c76..c30279e718d6c228f6aea2a0e9205b6219c6b35e 100644 (file)
@@ -492,7 +492,8 @@ process_statistics_value_message (struct GNUNET_STATISTICS_Handle *h,
  *
  * @param h statistics handle
  * @param msg the watch value message
- * @return GNUNET_OK if the message was well-formed, GNUNET_SYSERR if not
+ * @return GNUNET_OK if the message was well-formed, GNUNET_SYSERR if not,
+ *         GNUNET_NO if this watch has been cancelled
  */
 static int
 process_watch_value (struct GNUNET_STATISTICS_Handle *h,
@@ -516,6 +517,8 @@ process_watch_value (struct GNUNET_STATISTICS_Handle *h,
     return GNUNET_SYSERR;
   }
   w = h->watches[wid];
+  if (NULL == w)  
+    return GNUNET_NO;  
   (void) w->proc (w->proc_cls, w->subsystem, w->name,
                   GNUNET_ntohll (wvm->value),
                   0 != (ntohl (wvm->flags) & GNUNET_STATISTICS_PERSIST_BIT));
@@ -534,7 +537,7 @@ receive_stats (void *cls, const struct GNUNET_MessageHeader *msg)
 {
   struct GNUNET_STATISTICS_Handle *h = cls;
   struct GNUNET_STATISTICS_GetHandle *c;
+  int ret;
 
   if (msg == NULL)
   {
@@ -594,9 +597,11 @@ receive_stats (void *cls, const struct GNUNET_MessageHeader *msg)
     return;
   case GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE:
     if (GNUNET_OK != 
-       process_watch_value (h, msg))
+       (ret = process_watch_value (h, msg)))
     {
       do_disconnect (h);
+      if (GNUNET_NO == ret)
+       h->backoff = GNUNET_TIME_UNIT_MILLISECONDS; 
       reconnect_later (h);
       return;
     }
@@ -1076,8 +1081,6 @@ GNUNET_STATISTICS_get_cancel (struct GNUNET_STATISTICS_GetHandle *gh)
 
 /**
  * Watch statistics from the peer (be notified whenever they change).
- * Note that the only way to cancel a "watch" request is to destroy
- * the statistics handle given as the first argument to this call.
  *
  * @param handle identification of the statistics service
  * @param subsystem limit to the specified subsystem, never NULL
@@ -1106,6 +1109,46 @@ GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle,
 }
 
 
+/**
+ * Stop watching statistics from the peer.  
+ *
+ * @param handle identification of the statistics service
+ * @param subsystem limit to the specified subsystem, never NULL
+ * @param name name of the statistic value, never NULL
+ * @param proc function to call on each value
+ * @param proc_cls closure for proc
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error (no such watch)
+ */
+int
+GNUNET_STATISTICS_watch_cancel (struct GNUNET_STATISTICS_Handle *handle,
+                               const char *subsystem, const char *name,
+                               GNUNET_STATISTICS_Iterator proc, void *proc_cls)
+{
+  struct GNUNET_STATISTICS_WatchEntry *w;
+  unsigned int i;
+
+  if (handle == NULL)
+    return GNUNET_SYSERR;
+  for (i=0;i<handle->watches_size;i++)
+  {
+    w = handle->watches[i];
+    if ( (w->proc == proc) &&
+        (w->proc_cls == proc_cls) &&
+        (0 == strcmp (w->name, name)) &&
+        (0 == strcmp (w->subsystem, subsystem)) )
+    {
+      GNUNET_free (w->name);
+      GNUNET_free (w->subsystem);
+      GNUNET_free (w);
+      handle->watches[i] = NULL;      
+      return GNUNET_OK;
+    }   
+  }
+  return GNUNET_SYSERR;
+}
+
+
+
 /**
  * Queue a request to change a statistic.
  *