GNUnet  0.10.x
statistics_api.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009, 2010, 2011, 2016 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_protocols.h"
31 #include "statistics.h"
32 
38 #define SET_TRANSMIT_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 2)
39 
40 #define LOG(kind, ...) GNUNET_log_from(kind, "statistics-api", __VA_ARGS__)
41 
45 enum ActionType {
50 
55 
60 
65 };
66 
67 
75  char *subsystem;
76 
80  char *name;
81 
86 
90  void *proc_cls;
91 };
92 
93 
102 
107 
112 
116  char *subsystem;
117 
121  char *name;
122 
127 
132 
136  void *cls;
137 
142 
146  uint64_t value;
147 
152 
156  int aborted;
157 
162 
166  uint16_t msize;
167 };
168 
169 
177  char *subsystem;
178 
183 
188 
194 
199 
206 
211 
216 
221 
226 
230  uint64_t peak_heap_size;
231 
235  uint64_t peak_rss;
236 
240  unsigned int watches_size;
241 
247 
252 };
253 
254 
259 static void
261 {
262 #if ENABLE_HEAP_STATISTICS
263  uint64_t current_heap_size = 0;
264  uint64_t current_rss = 0;
265 
266  if (GNUNET_NO != h->do_destroy)
267  return;
268 #if HAVE_MALLINFO
269  {
270  struct mallinfo mi;
271 
272  mi = mallinfo();
273  current_heap_size = mi.uordblks + mi.fordblks;
274  }
275 #endif
276 #if HAVE_GETRUSAGE
277  {
278  struct rusage ru;
279 
280  if (0 == getrusage(RUSAGE_SELF, &ru))
281  {
282  current_rss = 1024LL * ru.ru_maxrss;
283  }
284  }
285 #endif
286  if (current_heap_size > h->peak_heap_size)
287  {
288  h->peak_heap_size = current_heap_size;
290  "# peak heap size",
291  current_heap_size,
292  GNUNET_NO);
293  }
294  if (current_rss > h->peak_rss)
295  {
296  h->peak_rss = current_rss;
298  "# peak resident set size",
299  current_rss,
300  GNUNET_NO);
301  }
302 #endif
303 }
304 
305 
311 static void
313 
314 
320 static void
321 schedule_action(void *cls);
322 
323 
331 static void
334 {
336  size_t slen;
337  size_t nlen;
338  size_t nsize;
339 
340  slen = strlen(watch->subsystem) + 1;
341  nlen = strlen(watch->name) + 1;
342  nsize = sizeof(struct GNUNET_MessageHeader) + slen + nlen;
343  if (nsize >= GNUNET_MAX_MESSAGE_SIZE)
344  {
345  GNUNET_break(0);
346  return;
347  }
349  ai->sh = h;
350  ai->subsystem = GNUNET_strdup(watch->subsystem);
351  ai->name = GNUNET_strdup(watch->name);
353  ai->msize = nsize;
354  ai->type = ACTION_WATCH;
355  ai->proc = watch->proc;
356  ai->cls = watch->proc_cls;
358  h->action_tail,
359  ai);
360  schedule_action(h);
361 }
362 
363 
369 static void
371 {
374  GNUNET_free(gh);
375 }
376 
377 
383 static void
385 {
386  struct GNUNET_STATISTICS_GetHandle *c;
387 
388  h->receiving = GNUNET_NO;
389  if (NULL != (c = h->current))
390  {
391  h->current = NULL;
392  if ((NULL != c->cont) &&
393  (GNUNET_YES != c->aborted))
394  {
395  c->cont(c->cls,
396  GNUNET_SYSERR);
397  c->cont = NULL;
398  }
399  free_action_item(c);
400  }
401  if (NULL != h->mq)
402  {
403  GNUNET_MQ_destroy(h->mq);
404  h->mq = NULL;
405  }
406 }
407 
408 
416 static int
418  const struct GNUNET_STATISTICS_ReplyMessage *smsg)
419 {
420  const char *service;
421  const char *name;
422  uint16_t size;
423 
424  size = ntohs(smsg->header.size);
425  size -= sizeof(struct GNUNET_STATISTICS_ReplyMessage);
426  if (size !=
427  GNUNET_STRINGS_buffer_tokenize((const char *)&smsg[1],
428  size,
429  2,
430  &service,
431  &name))
432  {
433  GNUNET_break(0);
434  return GNUNET_SYSERR;
435  }
436  return GNUNET_OK;
437 }
438 
439 
447 static void
449  const struct GNUNET_STATISTICS_ReplyMessage *smsg)
450 {
451  struct GNUNET_STATISTICS_Handle *h = cls;
452  const char *service;
453  const char *name;
454  uint16_t size;
455 
456  if (h->current->aborted)
457  return; /* iteration aborted, don't bother */
458 
459  size = ntohs(smsg->header.size);
460  size -= sizeof(struct GNUNET_STATISTICS_ReplyMessage);
461  GNUNET_assert(size ==
462  GNUNET_STRINGS_buffer_tokenize((const char *)&smsg[1],
463  size,
464  2,
465  &service,
466  &name));
468  "Received valid statistic on `%s:%s': %llu\n",
469  service, name,
470  GNUNET_ntohll(smsg->value));
471  if (GNUNET_OK !=
472  h->current->proc(h->current->cls,
473  service,
474  name,
475  GNUNET_ntohll(smsg->value),
476  0 !=
477  (ntohl(smsg->uid) & GNUNET_STATISTICS_PERSIST_BIT)))
478  {
480  "Processing of remaining statistics aborted by client.\n");
481  h->current->aborted = GNUNET_YES;
482  }
483 }
484 
485 
492 static void
494  const struct GNUNET_STATISTICS_WatchValueMessage *wvm)
495 {
496  struct GNUNET_STATISTICS_Handle *h = cls;
498  uint32_t wid;
499 
500  GNUNET_break(0 == ntohl(wvm->reserved));
501  wid = ntohl(wvm->wid);
502  if (wid >= h->watches_size)
503  {
504  do_disconnect(h);
505  reconnect_later(h);
506  return;
507  }
508  w = h->watches[wid];
509  if (NULL == w)
510  return;
511  (void)w->proc(w->proc_cls,
512  w->subsystem,
513  w->name,
514  GNUNET_ntohll(wvm->value),
515  0 != (ntohl(wvm->flags) & GNUNET_STATISTICS_PERSIST_BIT));
516 }
517 
518 
527 static void
529  enum GNUNET_MQ_Error error)
530 {
531  struct GNUNET_STATISTICS_Handle *h = cls;
532 
533  if (GNUNET_NO != h->do_destroy)
534  {
535  h->do_destroy = GNUNET_NO;
536  if (NULL != h->destroy_task)
537  {
539  h->destroy_task = NULL;
540  }
542  GNUNET_NO);
543  return;
544  }
545  do_disconnect(h);
546  reconnect_later(h);
547 }
548 
549 
555 static void
556 do_destroy(void *cls)
557 {
558  struct GNUNET_STATISTICS_Handle *h = cls;
559 
560  h->destroy_task = NULL;
561  h->do_destroy = GNUNET_NO;
563  "Running final destruction\n");
565  GNUNET_NO);
566 }
567 
568 
577 static void
579  const struct GNUNET_MessageHeader *msg)
580 {
581  struct GNUNET_STATISTICS_Handle *h = cls;
582 
583  if (GNUNET_SYSERR != h->do_destroy)
584  {
585  /* not in shutdown, why do we get 'TEST'? */
586  GNUNET_break(0);
587  do_disconnect(h);
588  reconnect_later(h);
589  return;
590  }
592  "Received DISCONNNECT_CONFIRM message from statistics, can complete disconnect\n");
593  if (NULL != h->destroy_task)
596  h);
597 }
598 
599 
608 static void
610  const struct GNUNET_MessageHeader *msg)
611 {
612  struct GNUNET_STATISTICS_Handle *h = cls;
613  struct GNUNET_STATISTICS_GetHandle *c;
614 
616  "Received end of statistics marker\n");
617  if (NULL == (c = h->current))
618  {
619  GNUNET_break(0);
620  do_disconnect(h);
621  reconnect_later(h);
622  return;
623  }
625  h->current = NULL;
626  schedule_action(h);
627  if (NULL != c->cont)
628  {
629  c->cont(c->cls,
630  GNUNET_OK);
631  c->cont = NULL;
632  }
633  free_action_item(c);
634 }
635 
636 
643 static int
645 {
646  struct GNUNET_MQ_MessageHandler handlers[] = {
647  GNUNET_MQ_hd_fixed_size(disconnect_confirm,
649  struct GNUNET_MessageHeader,
650  h),
651  GNUNET_MQ_hd_fixed_size(statistics_end,
653  struct GNUNET_MessageHeader,
654  h),
655  GNUNET_MQ_hd_var_size(statistics_value,
658  h),
659  GNUNET_MQ_hd_fixed_size(statistics_watch_value,
662  h),
664  };
666  struct GNUNET_STATISTICS_GetHandle *gn;
667 
668  if (NULL != h->backoff_task)
669  return GNUNET_NO;
670  if (NULL != h->mq)
671  return GNUNET_YES;
672  h->mq = GNUNET_CLIENT_connect(h->cfg,
673  "statistics",
674  handlers,
676  h);
677  if (NULL == h->mq)
678  {
680  "Failed to connect to statistics service!\n");
681  return GNUNET_NO;
682  }
683  gn = h->action_head;
684  while (NULL != (gh = gn))
685  {
686  gn = gh->next;
687  if (gh->type == ACTION_WATCH)
688  {
690  h->action_tail,
691  gh);
692  free_action_item(gh);
693  }
694  }
695  for (unsigned int i = 0; i < h->watches_size; i++)
696  if (NULL != h->watches[i])
698  h->watches[i]);
699  return GNUNET_YES;
700 }
701 
702 
708 static void
710 {
711  struct GNUNET_STATISTICS_Handle *h = cls;
712 
713  h->backoff_task = NULL;
714  schedule_action(h);
715 }
716 
717 
723 static void
725 {
726  int loss;
728 
729  GNUNET_assert(NULL == h->backoff_task);
730  if (GNUNET_YES == h->do_destroy)
731  {
732  /* So we are shutting down and the service is not reachable.
733  * Chances are that it's down for good and we are not going to connect to
734  * it anymore.
735  * Give up and don't sync the rest of the data.
736  */
737  loss = GNUNET_NO;
738  for (gh = h->action_head; NULL != gh; gh = gh->next)
739  if ((gh->make_persistent) &&
740  (ACTION_SET == gh->type))
741  loss = GNUNET_YES;
742  if (GNUNET_YES == loss)
744  _("Could not save some persistent statistics\n"));
745  if (NULL != h->destroy_task)
748  h);
749  return;
750  }
751  h->backoff_task
754  h);
756 }
757 
758 
759 
766 static void
768 {
769  struct GNUNET_STATISTICS_GetHandle *c;
770  struct GNUNET_MessageHeader *hdr;
771  struct GNUNET_MQ_Envelope *env;
772  size_t slen1;
773  size_t slen2;
774 
775  GNUNET_assert(NULL != (c = handle->current));
776  slen1 = strlen(c->subsystem) + 1;
777  slen2 = strlen(c->name) + 1;
778  env = GNUNET_MQ_msg_extra(hdr,
779  slen1 + slen2,
781  GNUNET_assert(slen1 + slen2 ==
782  GNUNET_STRINGS_buffer_fill((char *)&hdr[1],
783  slen1 + slen2,
784  2,
785  c->subsystem,
786  c->name));
789  handle);
790  GNUNET_MQ_send(handle->mq,
791  env);
792 }
793 
794 
801 static void
803 {
804  struct GNUNET_MessageHeader *hdr;
805  struct GNUNET_MQ_Envelope *env;
806  size_t slen1;
807  size_t slen2;
808 
810  "Transmitting watch request for `%s'\n",
811  handle->current->name);
812  slen1 = strlen(handle->current->subsystem) + 1;
813  slen2 = strlen(handle->current->name) + 1;
814  env = GNUNET_MQ_msg_extra(hdr,
815  slen1 + slen2,
817  GNUNET_assert(slen1 + slen2 ==
818  GNUNET_STRINGS_buffer_fill((char *)&hdr[1],
819  slen1 + slen2,
820  2,
821  handle->current->subsystem,
822  handle->current->name));
825  handle);
826  GNUNET_MQ_send(handle->mq,
827  env);
828  GNUNET_assert(NULL == handle->current->cont);
829  free_action_item(handle->current);
830  handle->current = NULL;
831  schedule_action(handle);
832 }
833 
834 
840 static void
842 {
844  struct GNUNET_MQ_Envelope *env;
845  size_t slen;
846  size_t nlen;
847 
848  slen = strlen(handle->current->subsystem) + 1;
849  nlen = strlen(handle->current->name) + 1;
850  env = GNUNET_MQ_msg_extra(r,
851  slen + nlen,
853  r->flags = 0;
854  r->value = GNUNET_htonll(handle->current->value);
855  if (handle->current->make_persistent)
857  if (handle->current->type == ACTION_UPDATE)
859  GNUNET_assert(slen + nlen ==
860  GNUNET_STRINGS_buffer_fill((char *)&r[1],
861  slen + nlen,
862  2,
863  handle->current->subsystem,
864  handle->current->name));
865  GNUNET_assert(NULL == handle->current->cont);
866  free_action_item(handle->current);
867  handle->current = NULL;
868  update_memory_statistics(handle);
871  handle);
872  GNUNET_MQ_send(handle->mq,
873  env);
874 }
875 
876 
886  const struct GNUNET_CONFIGURATION_Handle *cfg)
887 {
888  struct GNUNET_STATISTICS_Handle *h;
889 
890  if (GNUNET_YES ==
892  "statistics",
893  "DISABLE"))
894  return NULL;
896  h->cfg = cfg;
897  h->subsystem = GNUNET_strdup(subsystem);
899  return h;
900 }
901 
902 
911 void
913  int sync_first)
914 {
915  struct GNUNET_STATISTICS_GetHandle *pos;
917 
918  if (NULL == h)
919  return;
920  GNUNET_assert(GNUNET_NO == h->do_destroy); /* Don't call twice. */
921  if ((sync_first) &&
922  (NULL != h->mq) &&
923  (0 != GNUNET_MQ_get_length(h->mq)))
924  {
925  if ((NULL != h->current) &&
926  (ACTION_GET == h->current->type))
927  h->current->aborted = GNUNET_YES;
928  next = h->action_head;
929  while (NULL != (pos = next))
930  {
931  next = pos->next;
932  if ((ACTION_GET == pos->type) ||
933  (ACTION_WATCH == pos->type))
934  {
936  h->action_tail,
937  pos);
938  free_action_item(pos);
939  }
940  }
941  h->do_destroy = GNUNET_YES;
942  schedule_action(h);
943  GNUNET_assert(NULL == h->destroy_task);
944  h->destroy_task
946  5),
947  &do_destroy,
948  h);
950  "Deferring destruction\n");
951  return; /* do not finish destruction just yet */
952  }
953  /* do clean up all */
955  "Cleaning all up\n");
956  while (NULL != (pos = h->action_head))
957  {
959  h->action_tail,
960  pos);
961  free_action_item(pos);
962  }
963  do_disconnect(h);
964  if (NULL != h->backoff_task)
965  {
967  h->backoff_task = NULL;
968  }
969  if (NULL != h->destroy_task)
970  {
971  GNUNET_break(0);
973  h->destroy_task = NULL;
974  }
975  for (unsigned int i = 0; i < h->watches_size; i++)
976  {
977  if (NULL == h->watches[i])
978  continue;
979  GNUNET_free(h->watches[i]->subsystem);
980  GNUNET_free(h->watches[i]->name);
981  GNUNET_free(h->watches[i]);
982  }
984  h->watches_size,
985  0);
987  GNUNET_free(h);
988 }
989 
990 
996 static void
998 {
999  struct GNUNET_STATISTICS_Handle *h = cls;
1000 
1001  if (NULL != h->backoff_task)
1002  return; /* action already pending */
1003  if (GNUNET_YES != try_connect(h))
1004  {
1005  reconnect_later(h);
1006  return;
1007  }
1008  if (0 < GNUNET_MQ_get_length(h->mq))
1009  return; /* Wait for queue to be reduced more */
1010  /* schedule next action */
1011  while (NULL == h->current)
1012  {
1013  h->current = h->action_head;
1014  if (NULL == h->current)
1015  {
1016  struct GNUNET_MessageHeader *hdr;
1017  struct GNUNET_MQ_Envelope *env;
1018 
1019  if (GNUNET_YES != h->do_destroy)
1020  return; /* nothing to do */
1021  /* let service know that we're done */
1023  "Notifying service that we are done\n");
1024  h->do_destroy = GNUNET_SYSERR; /* in 'TEST' mode */
1025  env = GNUNET_MQ_msg(hdr,
1028  &schedule_action,
1029  h);
1030  GNUNET_MQ_send(h->mq,
1031  env);
1032  return;
1033  }
1035  h->action_tail,
1036  h->current);
1037  switch (h->current->type)
1038  {
1039  case ACTION_GET:
1040  transmit_get(h);
1041  break;
1042 
1043  case ACTION_SET:
1044  case ACTION_UPDATE:
1045  transmit_set(h);
1046  break;
1047 
1048  case ACTION_WATCH:
1049  transmit_watch(h);
1050  break;
1051 
1052  default:
1053  GNUNET_assert(0);
1054  break;
1055  }
1056  }
1057 }
1058 
1059 
1074  const char *subsystem,
1075  const char *name,
1078  void *cls)
1079 {
1080  size_t slen1;
1081  size_t slen2;
1083 
1084  if (NULL == handle)
1085  return NULL;
1086  GNUNET_assert(NULL != proc);
1087  GNUNET_assert(GNUNET_NO == handle->do_destroy);
1088  if (NULL == subsystem)
1089  subsystem = "";
1090  if (NULL == name)
1091  name = "";
1092  slen1 = strlen(subsystem) + 1;
1093  slen2 = strlen(name) + 1;
1094  GNUNET_assert(slen1 + slen2 + sizeof(struct GNUNET_MessageHeader) <
1097  ai->sh = handle;
1098  ai->subsystem = GNUNET_strdup(subsystem);
1099  ai->name = GNUNET_strdup(name);
1100  ai->cont = cont;
1101  ai->proc = proc;
1102  ai->cls = cls;
1103  ai->type = ACTION_GET;
1104  ai->msize = slen1 + slen2 + sizeof(struct GNUNET_MessageHeader);
1106  handle->action_tail,
1107  ai);
1108  schedule_action(handle);
1109  return ai;
1110 }
1111 
1112 
1119 void
1121 {
1122  if (NULL == gh)
1123  return;
1124  gh->cont = NULL;
1125  if (gh->sh->current == gh)
1126  {
1127  gh->aborted = GNUNET_YES;
1128  return;
1129  }
1131  gh->sh->action_tail,
1132  gh);
1133  GNUNET_free(gh->name);
1134  GNUNET_free(gh->subsystem);
1135  GNUNET_free(gh);
1136 }
1137 
1138 
1149 int
1151  const char *subsystem,
1152  const char *name,
1154  void *proc_cls)
1155 {
1156  struct GNUNET_STATISTICS_WatchEntry *w;
1157 
1158  if (NULL == handle)
1159  return GNUNET_SYSERR;
1161  w->subsystem = GNUNET_strdup(subsystem);
1162  w->name = GNUNET_strdup(name);
1163  w->proc = proc;
1164  w->proc_cls = proc_cls;
1165  GNUNET_array_append(handle->watches,
1166  handle->watches_size,
1167  w);
1168  schedule_watch_request(handle,
1169  w);
1170  return GNUNET_OK;
1171 }
1172 
1173 
1184 int
1186  const char *subsystem,
1187  const char *name,
1189  void *proc_cls)
1190 {
1191  struct GNUNET_STATISTICS_WatchEntry *w;
1192 
1193  if (NULL == handle)
1194  return GNUNET_SYSERR;
1195  for (unsigned int i = 0; i < handle->watches_size; i++)
1196  {
1197  w = handle->watches[i];
1198  if (NULL == w)
1199  continue;
1200  if ((w->proc == proc) &&
1201  (w->proc_cls == proc_cls) &&
1202  (0 == strcmp(w->name,
1203  name)) &&
1204  (0 == strcmp(w->subsystem,
1205  subsystem)))
1206  {
1207  GNUNET_free(w->name);
1208  GNUNET_free(w->subsystem);
1209  GNUNET_free(w);
1210  handle->watches[i] = NULL;
1211  return GNUNET_OK;
1212  }
1213  }
1214  return GNUNET_SYSERR;
1215 }
1216 
1217 
1227 static void
1229  const char *name,
1230  int make_persistent,
1231  uint64_t value,
1232  enum ActionType type)
1233 {
1235  size_t slen;
1236  size_t nlen;
1237  size_t nsize;
1238  int64_t delta;
1239 
1240  slen = strlen(h->subsystem) + 1;
1241  nlen = strlen(name) + 1;
1242  nsize = sizeof(struct GNUNET_STATISTICS_SetMessage) + slen + nlen;
1243  if (nsize >= GNUNET_MAX_MESSAGE_SIZE)
1244  {
1245  GNUNET_break(0);
1246  return;
1247  }
1248  for (ai = h->action_head; NULL != ai; ai = ai->next)
1249  {
1250  if (!((0 == strcmp(ai->subsystem,
1251  h->subsystem)) &&
1252  (0 == strcmp(ai->name,
1253  name)) &&
1254  ((ACTION_UPDATE == ai->type) ||
1255  (ACTION_SET == ai->type))))
1256  continue;
1257  if (ACTION_SET == ai->type)
1258  {
1259  if (ACTION_UPDATE == type)
1260  {
1261  delta = (int64_t)value;
1262  if (delta > 0)
1263  {
1264  /* update old set by new delta */
1265  ai->value += delta;
1266  }
1267  else
1268  {
1269  /* update old set by new delta, but never go negative */
1270  if (ai->value < -delta)
1271  ai->value = 0;
1272  else
1273  ai->value += delta;
1274  }
1275  }
1276  else
1277  {
1278  /* new set overrides old set */
1279  ai->value = value;
1280  }
1281  }
1282  else
1283  {
1284  if (ACTION_UPDATE == type)
1285  {
1286  /* make delta cummulative */
1287  delta = (int64_t)value;
1288  ai->value += delta;
1289  }
1290  else
1291  {
1292  /* drop old 'update', use new 'set' instead */
1293  ai->value = value;
1294  ai->type = type;
1295  }
1296  }
1297  ai->timeout
1299  ai->make_persistent
1300  = make_persistent;
1301  return;
1302  }
1303  /* no existing entry matches, create a fresh one */
1305  ai->sh = h;
1306  ai->subsystem = GNUNET_strdup(h->subsystem);
1307  ai->name = GNUNET_strdup(name);
1309  ai->make_persistent = make_persistent;
1310  ai->msize = nsize;
1311  ai->value = value;
1312  ai->type = type;
1314  h->action_tail,
1315  ai);
1316  schedule_action(h);
1317 }
1318 
1319 
1329 void
1331  const char *name,
1332  uint64_t value,
1333  int make_persistent)
1334 {
1335  if (NULL == handle)
1336  return;
1337  GNUNET_assert(GNUNET_NO == handle->do_destroy);
1338  add_setter_action(handle,
1339  name,
1340  make_persistent,
1341  value,
1342  ACTION_SET);
1343 }
1344 
1345 
1355 void
1357  const char *name,
1358  int64_t delta,
1359  int make_persistent)
1360 {
1361  if (NULL == handle)
1362  return;
1363  if (0 == delta)
1364  return;
1365  GNUNET_assert(GNUNET_NO == handle->do_destroy);
1366  add_setter_action(handle,
1367  name,
1368  make_persistent,
1369  (uint64_t)delta,
1370  ACTION_UPDATE);
1371 }
1372 
1373 
1374 /* end of statistics_api.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
int do_destroy
Should this handle auto-destruct once all actions have been processed?
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_STATISTICS_VALUE.
Definition: statistics.h:44
int make_persistent
Flag for SET/UPDATE actions.
char * name
What value is this action about? (can be NULL)
#define LOG(kind,...)
char * subsystem
Name of our subsystem.
static void reconnect_later(struct GNUNET_STATISTICS_Handle *h)
Reconnect at a later time, respecting back-off.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static void transmit_set(struct GNUNET_STATISTICS_Handle *handle)
Transmit a SET/UPDATE request.
#define GNUNET_MESSAGE_TYPE_STATISTICS_SET
Set a statistical value.
struct GNUNET_STATISTICS_WatchEntry ** watches
Array of watch entries.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static void handle_disconnect_confirm(void *cls, const struct GNUNET_MessageHeader *msg)
Handle a GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT_CONFIRM message.
void * proc_cls
Closure for proc.
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
#define GNUNET_MESSAGE_TYPE_STATISTICS_END
Response to a STATISTICS_GET message (end of value stream).
GNUNET_STATISTICS_Iterator proc
Function to call (for GET actions only).
static struct GNUNET_TIME_Relative backoff
How long should we wait to reconnect?
Definition: resolver_api.c:81
static void update_memory_statistics(struct GNUNET_STATISTICS_Handle *h)
Obtain statistics about this process&#39;s memory consumption and report those as well (if they changed)...
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:900
#define GNUNET_MESSAGE_TYPE_STATISTICS_WATCH
Watch changes to a statistical value.
Statistics message.
Definition: statistics.h:40
char * subsystem
What subsystem is this action about? (can be NULL)
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
enum ActionType type
Is this a ACTION_GET, ACTION_SET, ACTION_UPDATE or ACTION_WATCH?
static void do_disconnect(struct GNUNET_STATISTICS_Handle *h)
Disconnect from the statistics service.
char * name
What value is this action about? (never NULL)
void GNUNET_STATISTICS_get_cancel(struct GNUNET_STATISTICS_GetHandle *gh)
Cancel a &#39;get&#39; request.
int receiving
Are we currently receiving from the service?
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
Linked list of things we still need to do.
#define GNUNET_NO
Definition: gnunet_common.h:78
Message to set a statistic.
Definition: statistics.h:90
uint16_t msize
Size of the message that we will be transmitting.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_MESSAGE_TYPE_STATISTICS_VALUE
Response to a STATISTICS_GET message (with value).
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
uint32_t flags
0 for absolute value, 1 for relative value; 2 to make persistent (see GNUNET_STATISTICS_SETFLAG_*).
Definition: statistics.h:123
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint32_t reserved
Reserved (always 0).
Definition: statistics.h:136
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
struct GNUNET_TIME_Absolute timeout
Timeout for this action.
uint64_t peak_rss
Maximum resident set side observed so far (if available).
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
Handle for the service.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
ActionType
Types of actions.
#define GNUNET_STATISTICS_SETFLAG_RELATIVE
The value being set is a relative change.
Definition: statistics.h:74
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
unsigned int GNUNET_STRINGS_buffer_tokenize(const char *buffer, size_t size, unsigned int count,...)
Given a buffer of a given size, find "count" 0-terminated strings in the buffer and assign the count ...
Definition: strings.c:135
Message transmitted if a watched value changes.
Definition: statistics.h:113
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
struct GNUNET_TIME_Relative backoff
Time for next connect retry.
Watch a value.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1237
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:114
#define GNUNET_MESSAGE_TYPE_STATISTICS_GET
Get a statistical value(s).
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore...
Definition: mq.c:772
static char * value
Value of the record to add/remove.
GNUNET_STATISTICS_Iterator proc
Function to call.
#define GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT_CONFIRM
Service confirms disconnect and that it is done processing all requests from the client.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:333
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1264
#define GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE
Changes to a watched value.
uint64_t value
Associated value.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:440
size_t GNUNET_STRINGS_buffer_fill(char *buffer, size_t size, unsigned int count,...)
Fill a buffer of the given size with count 0-terminated strings (given as varargs).
Definition: strings.c:65
struct GNUNET_SCHEDULER_Task * backoff_task
Task doing exponential back-off trying to reconnect.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
Message handler for a specific message type.
uint32_t wid
Unique watch identification number (watch requests are enumerated in the order they are received...
Definition: statistics.h:131
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
uint64_t peak_heap_size
Maximum heap size observed so far (if available).
static int try_connect(struct GNUNET_STATISTICS_Handle *h)
Try to (re)connect to the statistics service.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
#define GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT
Client is done sending service requests and will now disconnect.
int(* GNUNET_STATISTICS_Iterator)(void *cls, const char *subsystem, const char *name, uint64_t value, int is_persistent)
Callback function to process statistic values.
struct GNUNET_STATISTICS_GetHandle * action_tail
Tail of the linked list of actions (for fast append).
static void reconnect_task(void *cls)
We&#39;ve waited long enough, reconnect now.
static int watch
Watch value continuously.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
struct GNUNET_STATISTICS_GetHandle * prev
This is a doubly linked list.
#define GNUNET_STATISTICS_PERSIST_BIT
Flag for the struct GNUNET_STATISTICS_ReplyMessage UID only.
Definition: statistics.h:64
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
static void do_destroy(void *cls)
Task used to destroy the statistics handle.
GNUNET_STATISTICS_Callback cont
Continuation to call once action is complete.
struct GNUNET_SCHEDULER_Task * destroy_task
Task for running do_destroy().
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
struct GNUNET_STATISTICS_Handle * sh
Main statistics handle.
struct GNUNET_MQ_Handle * mq
Message queue to the service.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
Update a value.
Handle to a message queue.
Definition: mq.c:84
Get a value.
#define GNUNET_array_append(arr, size, element)
Append an element to a list (growing the list by one).
uint32_t flags
0 for absolute value, 1 for relative value; 2 to make persistent (see GNUNET_STATISTICS_SETFLAG_*).
Definition: statistics.h:100
int GNUNET_STATISTICS_watch_cancel(struct GNUNET_STATISTICS_Handle *handle, const char *subsystem, const char *name, GNUNET_STATISTICS_Iterator proc, void *proc_cls)
Stop watching statistics from the peer.
static void transmit_get(struct GNUNET_STATISTICS_Handle *handle)
Transmit a GET request (and if successful, start to receive the response).
#define SET_TRANSMIT_TIMEOUT
How long do we wait until a statistics request for setting a value times out? (The update will be los...
static void handle_statistics_value(void *cls, const struct GNUNET_STATISTICS_ReplyMessage *smsg)
Process a GNUNET_MESSAGE_TYPE_STATISTICS_VALUE message.
struct GNUNET_STATISTICS_GetHandle * GNUNET_STATISTICS_get(struct GNUNET_STATISTICS_Handle *handle, const char *subsystem, const char *name, GNUNET_STATISTICS_Callback cont, GNUNET_STATISTICS_Iterator proc, void *cls)
Get statistic from the peer.
configuration data
Definition: configuration.c:83
Set a value.
static void add_setter_action(struct GNUNET_STATISTICS_Handle *h, const char *name, int make_persistent, uint64_t value, enum ActionType type)
Queue a request to change a statistic.
static void schedule_action(void *cls)
Schedule the next action to be performed.
int GNUNET_STATISTICS_watch(struct GNUNET_STATISTICS_Handle *handle, const char *subsystem, const char *name, GNUNET_STATISTICS_Iterator proc, void *proc_cls)
Watch statistics from the peer (be notified whenever they change).
void * cls
Closure for proc and cont.
static struct GNUNET_TRANSPORT_HelloGetHandle * gh
Pending GNUNET_TRANSPORT_hello_get() operation.
static void schedule_watch_request(struct GNUNET_STATISTICS_Handle *h, struct GNUNET_STATISTICS_WatchEntry *watch)
Transmit request to service that we want to watch the development of a particular value...
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:131
void(* GNUNET_STATISTICS_Callback)(void *cls, int success)
Continuation called by GNUNET_STATISTICS_get() functions.
static void handle_statistics_watch_value(void *cls, const struct GNUNET_STATISTICS_WatchValueMessage *wvm)
We have received a watch value from the service.
struct GNUNET_STATISTICS_GetHandle * current
Action we are currently busy with (action request has been transmitted, we&#39;re now receiving the respo...
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:821
unsigned int watches_size
Size of the watches array.
#define GNUNET_YES
Definition: gnunet_common.h:77
Entry kept for each value we are watching.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:351
struct GNUNET_STATISTICS_GetHandle * next
This is a doubly linked list.
char * subsystem
What subsystem is this action about? (never NULL)
static void free_action_item(struct GNUNET_STATISTICS_GetHandle *gh)
Free memory associated with the given action item.
int GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
static int check_statistics_value(void *cls, const struct GNUNET_STATISTICS_ReplyMessage *smsg)
Process a GNUNET_MESSAGE_TYPE_STATISTICS_VALUE message.
static void transmit_watch(struct GNUNET_STATISTICS_Handle *handle)
Transmit a WATCH request (and if successful, start to receive the response).
struct GNUNET_STATISTICS_GetHandle * action_head
Head of the linked list of pending actions (first action to be performed).
int aborted
Has the current iteration been aborted; for GET actions.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
#define GNUNET_STATISTICS_SETFLAG_PERSISTENT
The value being set is to be persistent (note that this bit can be combined with GNUNET_STATISTICS_SE...
Definition: statistics.h:82
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
static void handle_statistics_end(void *cls, const struct GNUNET_MessageHeader *msg)
Handle a GNUNET_MESSAGE_TYPE_STATISTICS_END message.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956