*
* @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,
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));
{
struct GNUNET_STATISTICS_Handle *h = cls;
struct GNUNET_STATISTICS_GetHandle *c;
-
+ int ret;
if (msg == NULL)
{
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;
}
{
struct GNUNET_STATISTICS_GetHandle *pos;
struct GNUNET_STATISTICS_GetHandle *next;
- struct GNUNET_STATISTICS_GetHandle *prev;
struct GNUNET_TIME_Relative timeout;
int i;
h->current = NULL;
}
}
- pos = h->action_head;
- prev = NULL;
- while (pos != NULL)
+ next = h->action_head;
+ while (NULL != (pos = next))
{
next = pos->next;
if (pos->type == ACTION_GET)
{
- if (prev == NULL)
- h->action_head = next;
- else
- prev->next = next;
+ GNUNET_CONTAINER_DLL_remove (h->action_head,
+ h->action_tail,
+ pos);
free_action_item (pos);
}
- else
- {
- prev = pos;
- }
- pos = next;
- }
- h->action_tail = prev;
- if (h->current == NULL)
- {
- h->current = h->action_head;
- if (h->action_head != NULL)
- {
- h->action_head = h->action_head->next;
- if (h->action_head == NULL)
- h->action_tail = NULL;
- }
}
+ if ( (NULL == h->current) &&
+ (NULL != (h->current = h->action_head)) )
+ GNUNET_CONTAINER_DLL_remove (h->action_head,
+ h->action_tail,
+ h->current);
h->do_destroy = GNUNET_YES;
if ((h->current != NULL) && (h->th == NULL))
{
}
}
if (h->th != NULL)
- return;
+ return; /* do not finish destruction just yet */
}
while (NULL != (pos = h->action_head))
{
/**
* 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
}
+/**
+ * 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.
*