aboutsummaryrefslogtreecommitdiff
path: root/src/statistics/statistics_api.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-03-12 12:36:50 +0000
committerChristian Grothoff <christian@grothoff.org>2010-03-12 12:36:50 +0000
commit61cfd3340e67672f351ab92dab7da72dca058c79 (patch)
tree7144d056b877397aff501ec7f36e42f659350be8 /src/statistics/statistics_api.c
parent6324d68ac07d6cc498c934727ba5970909741c85 (diff)
downloadgnunet-61cfd3340e67672f351ab92dab7da72dca058c79.tar.gz
gnunet-61cfd3340e67672f351ab92dab7da72dca058c79.zip
enable stats get cancellation
Diffstat (limited to 'src/statistics/statistics_api.c')
-rw-r--r--src/statistics/statistics_api.c120
1 files changed, 75 insertions, 45 deletions
diff --git a/src/statistics/statistics_api.c b/src/statistics/statistics_api.c
index 86950ad4c..e9ebe7fa6 100644
--- a/src/statistics/statistics_api.c
+++ b/src/statistics/statistics_api.c
@@ -25,6 +25,7 @@
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_client_lib.h" 27#include "gnunet_client_lib.h"
28#include "gnunet_container_lib.h"
28#include "gnunet_protocols.h" 29#include "gnunet_protocols.h"
29#include "gnunet_server_lib.h" 30#include "gnunet_server_lib.h"
30#include "gnunet_statistics_service.h" 31#include "gnunet_statistics_service.h"
@@ -48,14 +49,25 @@ enum ActionType
48/** 49/**
49 * Linked list of things we still need to do. 50 * Linked list of things we still need to do.
50 */ 51 */
51struct ActionItem 52struct GNUNET_STATISTICS_GetHandle
52{ 53{
54
55 /**
56 * This is a doubly linked list.
57 */
58 struct GNUNET_STATISTICS_GetHandle *next;
59
53 /** 60 /**
54 * This is a linked list. 61 * This is a doubly linked list.
55 */ 62 */
56 struct ActionItem *next; 63 struct GNUNET_STATISTICS_GetHandle *prev;
57 64
58 /** 65 /**
66 * Main statistics handle.
67 */
68 struct GNUNET_STATISTICS_Handle *sh;
69
70 /**
59 * What subsystem is this action about? (can be NULL) 71 * What subsystem is this action about? (can be NULL)
60 */ 72 */
61 char *subsystem; 73 char *subsystem;
@@ -147,19 +159,19 @@ struct GNUNET_STATISTICS_Handle
147 * Head of the linked list of pending actions (first action 159 * Head of the linked list of pending actions (first action
148 * to be performed). 160 * to be performed).
149 */ 161 */
150 struct ActionItem *action_head; 162 struct GNUNET_STATISTICS_GetHandle *action_head;
151 163
152 /** 164 /**
153 * Tail of the linked list of actions (for fast append). 165 * Tail of the linked list of actions (for fast append).
154 */ 166 */
155 struct ActionItem *action_tail; 167 struct GNUNET_STATISTICS_GetHandle *action_tail;
156 168
157 /** 169 /**
158 * Action we are currently busy with (action request has been 170 * Action we are currently busy with (action request has been
159 * transmitted, we're now receiving the response from the 171 * transmitted, we're now receiving the response from the
160 * service). 172 * service).
161 */ 173 */
162 struct ActionItem *current; 174 struct GNUNET_STATISTICS_GetHandle *current;
163 175
164 /** 176 /**
165 * Should this handle auto-destruct once all actions have 177 * Should this handle auto-destruct once all actions have
@@ -195,7 +207,7 @@ try_connect (struct GNUNET_STATISTICS_Handle *ret)
195 * Free memory associated with the given action item. 207 * Free memory associated with the given action item.
196 */ 208 */
197static void 209static void
198free_action_item (struct ActionItem *ai) 210free_action_item (struct GNUNET_STATISTICS_GetHandle *ai)
199{ 211{
200 GNUNET_free_non_null (ai->subsystem); 212 GNUNET_free_non_null (ai->subsystem);
201 GNUNET_free_non_null (ai->name); 213 GNUNET_free_non_null (ai->name);
@@ -203,9 +215,6 @@ free_action_item (struct ActionItem *ai)
203} 215}
204 216
205 217
206
207
208
209/** 218/**
210 * Schedule the next action to be performed. 219 * Schedule the next action to be performed.
211 */ 220 */
@@ -218,7 +227,7 @@ static void schedule_action (struct GNUNET_STATISTICS_Handle *h);
218static void 227static void
219finish (struct GNUNET_STATISTICS_Handle *h, int code) 228finish (struct GNUNET_STATISTICS_Handle *h, int code)
220{ 229{
221 struct ActionItem *pos = h->current; 230 struct GNUNET_STATISTICS_GetHandle *pos = h->current;
222 h->current = NULL; 231 h->current = NULL;
223 schedule_action (h); 232 schedule_action (h);
224 if (pos->cont != NULL) 233 if (pos->cont != NULL)
@@ -264,17 +273,17 @@ process_message (struct GNUNET_STATISTICS_Handle *h,
264#endif 273#endif
265 if (GNUNET_OK != 274 if (GNUNET_OK !=
266 h->current->proc (h->current->cls, 275 h->current->proc (h->current->cls,
267 service, 276 service,
268 name, 277 name,
269 GNUNET_ntohll (smsg->value), 278 GNUNET_ntohll (smsg->value),
270 0 != 279 0 !=
271 (ntohl (smsg->uid) & GNUNET_STATISTICS_PERSIST_BIT))) 280 (ntohl (smsg->uid) & GNUNET_STATISTICS_PERSIST_BIT)))
272 { 281 {
273#if DEBUG_STATISTICS 282#if DEBUG_STATISTICS
274 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 283 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
275 "Processing of remaining statistics aborted by client.\n"); 284 "Processing of remaining statistics aborted by client.\n");
276#endif 285#endif
277 h->current->aborted = GNUNET_YES; 286 h->current->aborted = GNUNET_YES;
278 } 287 }
279 return GNUNET_OK; 288 return GNUNET_OK;
280} 289}
@@ -495,9 +504,9 @@ void
495GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h, 504GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h,
496 int sync_first) 505 int sync_first)
497{ 506{
498 struct ActionItem *pos; 507 struct GNUNET_STATISTICS_GetHandle *pos;
499 struct ActionItem *next; 508 struct GNUNET_STATISTICS_GetHandle *next;
500 struct ActionItem *prev; 509 struct GNUNET_STATISTICS_GetHandle *prev;
501 struct GNUNET_TIME_Relative timeout; 510 struct GNUNET_TIME_Relative timeout;
502 511
503 if (sync_first) 512 if (sync_first)
@@ -606,10 +615,9 @@ schedule_action (struct GNUNET_STATISTICS_Handle *h)
606 } 615 }
607 return; 616 return;
608 } 617 }
609 h->action_head = h->action_head->next; 618 GNUNET_CONTAINER_DLL_remove (h->action_head,
610 if (NULL == h->action_head) 619 h->action_tail,
611 h->action_tail = NULL; 620 h->current);
612 h->current->next = NULL;
613 timeout = GNUNET_TIME_absolute_get_remaining (h->current->timeout); 621 timeout = GNUNET_TIME_absolute_get_remaining (h->current->timeout);
614 if (NULL == 622 if (NULL ==
615 (h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, 623 (h->th = GNUNET_CLIENT_notify_transmit_ready (h->client,
@@ -628,19 +636,14 @@ schedule_action (struct GNUNET_STATISTICS_Handle *h)
628 636
629 637
630static void 638static void
631insert_ai (struct GNUNET_STATISTICS_Handle *h, struct ActionItem *ai) 639insert_ai (struct GNUNET_STATISTICS_Handle *h, struct GNUNET_STATISTICS_GetHandle *ai)
632{ 640{
633 if (h->action_tail == NULL) 641 GNUNET_CONTAINER_DLL_insert_after (h->action_head,
634 { 642 h->action_tail,
635 h->action_head = ai; 643 h->action_tail,
636 h->action_tail = ai; 644 ai);
637 schedule_action (h); 645 if (h->action_head == ai)
638 } 646 schedule_action (h);
639 else
640 {
641 h->action_tail->next = ai;
642 h->action_tail = ai;
643 }
644} 647}
645 648
646 649
@@ -655,8 +658,9 @@ insert_ai (struct GNUNET_STATISTICS_Handle *h, struct ActionItem *ai)
655 * @param cont continuation to call when done (can be NULL) 658 * @param cont continuation to call when done (can be NULL)
656 * @param proc function to call on each value 659 * @param proc function to call on each value
657 * @param cls closure for cont and proc 660 * @param cls closure for cont and proc
661 * @return NULL on error
658 */ 662 */
659void 663struct GNUNET_STATISTICS_GetHandle *
660GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle, 664GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle,
661 const char *subsystem, 665 const char *subsystem,
662 const char *name, 666 const char *name,
@@ -666,7 +670,7 @@ GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle,
666{ 670{
667 size_t slen1; 671 size_t slen1;
668 size_t slen2; 672 size_t slen2;
669 struct ActionItem *ai; 673 struct GNUNET_STATISTICS_GetHandle *ai;
670 674
671 GNUNET_assert (handle != NULL); 675 GNUNET_assert (handle != NULL);
672 GNUNET_assert (proc != NULL); 676 GNUNET_assert (proc != NULL);
@@ -679,9 +683,7 @@ GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle,
679 strlen (subsystem) ? subsystem : "*", 683 strlen (subsystem) ? subsystem : "*",
680 strlen (name) ? name : "*"); 684 strlen (name) ? name : "*");
681#endif 685#endif
682 if (cont != NULL) 686 return NULL;
683 cont (cls, GNUNET_SYSERR);
684 return;
685 } 687 }
686 if (subsystem == NULL) 688 if (subsystem == NULL)
687 subsystem = ""; 689 subsystem = "";
@@ -691,7 +693,8 @@ GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle,
691 slen2 = strlen (name); 693 slen2 = strlen (name);
692 GNUNET_assert (slen1 + slen2 + sizeof (struct GNUNET_MessageHeader) < 694 GNUNET_assert (slen1 + slen2 + sizeof (struct GNUNET_MessageHeader) <
693 GNUNET_SERVER_MAX_MESSAGE_SIZE); 695 GNUNET_SERVER_MAX_MESSAGE_SIZE);
694 ai = GNUNET_malloc (sizeof (struct ActionItem)); 696 ai = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_GetHandle));
697 ai->sh = handle;
695 ai->subsystem = GNUNET_strdup (subsystem); 698 ai->subsystem = GNUNET_strdup (subsystem);
696 ai->name = GNUNET_strdup (name); 699 ai->name = GNUNET_strdup (name);
697 ai->cont = cont; 700 ai->cont = cont;
@@ -701,6 +704,32 @@ GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle,
701 ai->type = ACTION_GET; 704 ai->type = ACTION_GET;
702 ai->msize = slen1 + slen2 + sizeof (struct GNUNET_MessageHeader); 705 ai->msize = slen1 + slen2 + sizeof (struct GNUNET_MessageHeader);
703 insert_ai (handle, ai); 706 insert_ai (handle, ai);
707 return ai;
708}
709
710
711/**
712 * Cancel a 'get' request. Must be called before the 'cont'
713 * function is called.
714 *
715 * @param gh handle of the request to cancel
716 */
717void
718GNUNET_STATISTICS_get_cancel (struct GNUNET_STATISTICS_GetHandle *gh)
719{
720 if (gh->sh->current == gh)
721 {
722 gh->aborted = GNUNET_YES;
723 }
724 else
725 {
726 GNUNET_CONTAINER_DLL_remove (gh->sh->action_head,
727 gh->sh->action_tail,
728 gh);
729 GNUNET_free (gh->name);
730 GNUNET_free (gh->subsystem);
731 GNUNET_free (gh);
732 }
704} 733}
705 734
706 735
@@ -710,7 +739,7 @@ add_setter_action (struct GNUNET_STATISTICS_Handle *h,
710 int make_persistent, 739 int make_persistent,
711 uint64_t value, enum ActionType type) 740 uint64_t value, enum ActionType type)
712{ 741{
713 struct ActionItem *ai; 742 struct GNUNET_STATISTICS_GetHandle *ai;
714 size_t slen; 743 size_t slen;
715 size_t nlen; 744 size_t nlen;
716 size_t nsize; 745 size_t nsize;
@@ -727,7 +756,8 @@ add_setter_action (struct GNUNET_STATISTICS_Handle *h,
727 GNUNET_break (0); 756 GNUNET_break (0);
728 return; 757 return;
729 } 758 }
730 ai = GNUNET_malloc (sizeof (struct ActionItem)); 759 ai = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_GetHandle));
760 ai->sh = h;
731 ai->subsystem = GNUNET_strdup (h->subsystem); 761 ai->subsystem = GNUNET_strdup (h->subsystem);
732 ai->name = GNUNET_strdup (name); 762 ai->name = GNUNET_strdup (name);
733 ai->timeout = GNUNET_TIME_relative_to_absolute (SET_TRANSMIT_TIMEOUT); 763 ai->timeout = GNUNET_TIME_relative_to_absolute (SET_TRANSMIT_TIMEOUT);