aboutsummaryrefslogtreecommitdiff
path: root/src/statistics/statistics_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/statistics/statistics_api.c')
-rw-r--r--src/statistics/statistics_api.c702
1 files changed, 348 insertions, 354 deletions
diff --git a/src/statistics/statistics_api.c b/src/statistics/statistics_api.c
index 5d419f637..8e80a4d75 100644
--- a/src/statistics/statistics_api.c
+++ b/src/statistics/statistics_api.c
@@ -243,22 +243,24 @@ struct GNUNET_STATISTICS_Handle
243/** 243/**
244 * Schedule the next action to be performed. 244 * Schedule the next action to be performed.
245 */ 245 */
246static void schedule_action (struct GNUNET_STATISTICS_Handle *h); 246static void
247schedule_action (struct GNUNET_STATISTICS_Handle *h);
247 248
248/** 249/**
249 * Try to (re)connect to the statistics service. 250 * Try to (re)connect to the statistics service.
250 * 251 *
251 * @return GNUNET_YES on success, GNUNET_NO on failure. 252 * @return GNUNET_YES on success, GNUNET_NO on failure.
252 */ 253 */
253static int try_connect (struct GNUNET_STATISTICS_Handle *ret); 254static int
255try_connect (struct GNUNET_STATISTICS_Handle *ret);
254 256
255 257
256static void 258static void
257insert_ai (struct GNUNET_STATISTICS_Handle *h, 259insert_ai (struct GNUNET_STATISTICS_Handle *h,
258 struct GNUNET_STATISTICS_GetHandle *ai) 260 struct GNUNET_STATISTICS_GetHandle *ai)
259{ 261{
260 GNUNET_CONTAINER_DLL_insert_after (h->action_head, h->action_tail, 262 GNUNET_CONTAINER_DLL_insert_after (h->action_head, h->action_tail,
261 h->action_tail, ai); 263 h->action_tail, ai);
262 if (h->action_head == ai) 264 if (h->action_head == ai)
263 schedule_action (h); 265 schedule_action (h);
264} 266}
@@ -266,7 +268,7 @@ insert_ai (struct GNUNET_STATISTICS_Handle *h,
266 268
267static void 269static void
268schedule_watch_request (struct GNUNET_STATISTICS_Handle *h, 270schedule_watch_request (struct GNUNET_STATISTICS_Handle *h,
269 struct GNUNET_STATISTICS_WatchEntry *watch) 271 struct GNUNET_STATISTICS_WatchEntry *watch)
270{ 272{
271 273
272 struct GNUNET_STATISTICS_GetHandle *ai; 274 struct GNUNET_STATISTICS_GetHandle *ai;
@@ -276,18 +278,18 @@ schedule_watch_request (struct GNUNET_STATISTICS_Handle *h,
276 278
277 GNUNET_assert (h != NULL); 279 GNUNET_assert (h != NULL);
278 if (GNUNET_YES != try_connect (h)) 280 if (GNUNET_YES != try_connect (h))
279 { 281 {
280 schedule_action (h); 282 schedule_action (h);
281 return; 283 return;
282 } 284 }
283 slen = strlen (watch->subsystem) + 1; 285 slen = strlen (watch->subsystem) + 1;
284 nlen = strlen (watch->name) + 1; 286 nlen = strlen (watch->name) + 1;
285 nsize = sizeof (struct GNUNET_MessageHeader) + slen + nlen; 287 nsize = sizeof (struct GNUNET_MessageHeader) + slen + nlen;
286 if (nsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 288 if (nsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
287 { 289 {
288 GNUNET_break (0); 290 GNUNET_break (0);
289 return; 291 return;
290 } 292 }
291 ai = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_GetHandle)); 293 ai = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_GetHandle));
292 ai->sh = h; 294 ai->sh = h;
293 ai->subsystem = GNUNET_strdup (watch->subsystem); 295 ai->subsystem = GNUNET_strdup (watch->subsystem);
@@ -315,11 +317,11 @@ try_connect (struct GNUNET_STATISTICS_Handle *ret)
315 return GNUNET_YES; 317 return GNUNET_YES;
316 ret->client = GNUNET_CLIENT_connect ("statistics", ret->cfg); 318 ret->client = GNUNET_CLIENT_connect ("statistics", ret->cfg);
317 if (ret->client != NULL) 319 if (ret->client != NULL)
318 { 320 {
319 for (i = 0; i < ret->watches_size; i++) 321 for (i = 0; i < ret->watches_size; i++)
320 schedule_watch_request (ret, ret->watches[i]); 322 schedule_watch_request (ret, ret->watches[i]);
321 return GNUNET_YES; 323 return GNUNET_YES;
322 } 324 }
323#if DEBUG_STATISTICS 325#if DEBUG_STATISTICS
324 LOG (GNUNET_ERROR_TYPE_DEBUG, 326 LOG (GNUNET_ERROR_TYPE_DEBUG,
325 _("Failed to connect to statistics service!\n")); 327 _("Failed to connect to statistics service!\n"));
@@ -351,11 +353,11 @@ finish (struct GNUNET_STATISTICS_Handle *h, int code)
351 h->current = NULL; 353 h->current = NULL;
352 schedule_action (h); 354 schedule_action (h);
353 if (pos != NULL) 355 if (pos != NULL)
354 { 356 {
355 if (pos->cont != NULL) 357 if (pos->cont != NULL)
356 pos->cont (pos->cls, code); 358 pos->cont (pos->cls, code);
357 free_action_item (pos); 359 free_action_item (pos);
358 } 360 }
359} 361}
360 362
361 363
@@ -366,7 +368,7 @@ finish (struct GNUNET_STATISTICS_Handle *h, int code)
366 */ 368 */
367static int 369static int
368process_message (struct GNUNET_STATISTICS_Handle *h, 370process_message (struct GNUNET_STATISTICS_Handle *h,
369 const struct GNUNET_MessageHeader *msg) 371 const struct GNUNET_MessageHeader *msg)
370{ 372{
371 char *service; 373 char *service;
372 char *name; 374 char *name;
@@ -374,45 +376,43 @@ process_message (struct GNUNET_STATISTICS_Handle *h,
374 uint16_t size; 376 uint16_t size;
375 377
376 if (h->current->aborted) 378 if (h->current->aborted)
377 { 379 {
378#if DEBUG_STATISTICS 380#if DEBUG_STATISTICS
379 LOG (GNUNET_ERROR_TYPE_DEBUG, 381 LOG (GNUNET_ERROR_TYPE_DEBUG, "Iteration was aborted, ignoring VALUE\n");
380 "Iteration was aborted, ignoring VALUE\n");
381#endif 382#endif
382 return GNUNET_OK; /* don't bother */ 383 return GNUNET_OK; /* don't bother */
383 } 384 }
384 size = ntohs (msg->size); 385 size = ntohs (msg->size);
385 if (size < sizeof (struct GNUNET_STATISTICS_ReplyMessage)) 386 if (size < sizeof (struct GNUNET_STATISTICS_ReplyMessage))
386 { 387 {
387 GNUNET_break (0); 388 GNUNET_break (0);
388 return GNUNET_SYSERR; 389 return GNUNET_SYSERR;
389 } 390 }
390 smsg = (const struct GNUNET_STATISTICS_ReplyMessage *) msg; 391 smsg = (const struct GNUNET_STATISTICS_ReplyMessage *) msg;
391 size -= sizeof (struct GNUNET_STATISTICS_ReplyMessage); 392 size -= sizeof (struct GNUNET_STATISTICS_ReplyMessage);
392 if (size != 393 if (size !=
393 GNUNET_STRINGS_buffer_tokenize ((const char *) &smsg[1], size, 2, 394 GNUNET_STRINGS_buffer_tokenize ((const char *) &smsg[1], size, 2,
394 &service, &name)) 395 &service, &name))
395 { 396 {
396 GNUNET_break (0); 397 GNUNET_break (0);
397 return GNUNET_SYSERR; 398 return GNUNET_SYSERR;
398 } 399 }
399#if DEBUG_STATISTICS 400#if DEBUG_STATISTICS
400 LOG (GNUNET_ERROR_TYPE_DEBUG, 401 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received valid statistic on `%s:%s': %llu\n",
401 "Received valid statistic on `%s:%s': %llu\n", service, name, 402 service, name, GNUNET_ntohll (smsg->value));
402 GNUNET_ntohll (smsg->value));
403#endif 403#endif
404 if (GNUNET_OK != 404 if (GNUNET_OK !=
405 h->current->proc (h->current->cls, service, name, 405 h->current->proc (h->current->cls, service, name,
406 GNUNET_ntohll (smsg->value), 406 GNUNET_ntohll (smsg->value),
407 0 != 407 0 !=
408 (ntohl (smsg->uid) & GNUNET_STATISTICS_PERSIST_BIT))) 408 (ntohl (smsg->uid) & GNUNET_STATISTICS_PERSIST_BIT)))
409 { 409 {
410#if DEBUG_STATISTICS 410#if DEBUG_STATISTICS
411 LOG (GNUNET_ERROR_TYPE_DEBUG, 411 LOG (GNUNET_ERROR_TYPE_DEBUG,
412 "Processing of remaining statistics aborted by client.\n"); 412 "Processing of remaining statistics aborted by client.\n");
413#endif 413#endif
414 h->current->aborted = GNUNET_YES; 414 h->current->aborted = GNUNET_YES;
415 } 415 }
416#if DEBUG_STATISTICS 416#if DEBUG_STATISTICS
417 LOG (GNUNET_ERROR_TYPE_DEBUG, "VALUE processed successfully\n"); 417 LOG (GNUNET_ERROR_TYPE_DEBUG, "VALUE processed successfully\n");
418#endif 418#endif
@@ -422,30 +422,29 @@ process_message (struct GNUNET_STATISTICS_Handle *h,
422 422
423static int 423static int
424process_watch_value (struct GNUNET_STATISTICS_Handle *h, 424process_watch_value (struct GNUNET_STATISTICS_Handle *h,
425 const struct GNUNET_MessageHeader *msg) 425 const struct GNUNET_MessageHeader *msg)
426{ 426{
427 const struct GNUNET_STATISTICS_WatchValueMessage *wvm; 427 const struct GNUNET_STATISTICS_WatchValueMessage *wvm;
428 struct GNUNET_STATISTICS_WatchEntry *w; 428 struct GNUNET_STATISTICS_WatchEntry *w;
429 uint32_t wid; 429 uint32_t wid;
430 430
431 if (sizeof (struct GNUNET_STATISTICS_WatchValueMessage) != 431 if (sizeof (struct GNUNET_STATISTICS_WatchValueMessage) != ntohs (msg->size))
432 ntohs (msg->size)) 432 {
433 { 433 GNUNET_break (0);
434 GNUNET_break (0); 434 return GNUNET_SYSERR;
435 return GNUNET_SYSERR; 435 }
436 }
437 wvm = (const struct GNUNET_STATISTICS_WatchValueMessage *) msg; 436 wvm = (const struct GNUNET_STATISTICS_WatchValueMessage *) msg;
438 GNUNET_break (0 == ntohl (wvm->reserved)); 437 GNUNET_break (0 == ntohl (wvm->reserved));
439 wid = ntohl (wvm->wid); 438 wid = ntohl (wvm->wid);
440 if (wid >= h->watches_size) 439 if (wid >= h->watches_size)
441 { 440 {
442 GNUNET_break (0); 441 GNUNET_break (0);
443 return GNUNET_SYSERR; 442 return GNUNET_SYSERR;
444 } 443 }
445 w = h->watches[wid]; 444 w = h->watches[wid];
446 (void) w->proc (w->proc_cls, w->subsystem, w->name, 445 (void) w->proc (w->proc_cls, w->subsystem, w->name,
447 GNUNET_ntohll (wvm->value), 446 GNUNET_ntohll (wvm->value),
448 0 != (ntohl (wvm->flags) & GNUNET_STATISTICS_PERSIST_BIT)); 447 0 != (ntohl (wvm->flags) & GNUNET_STATISTICS_PERSIST_BIT));
449 return GNUNET_OK; 448 return GNUNET_OK;
450} 449}
451 450
@@ -462,73 +461,73 @@ receive_stats (void *cls, const struct GNUNET_MessageHeader *msg)
462 struct GNUNET_STATISTICS_Handle *h = cls; 461 struct GNUNET_STATISTICS_Handle *h = cls;
463 462
464 if (msg == NULL) 463 if (msg == NULL)
464 {
465 if (NULL != h->client)
465 { 466 {
466 if (NULL != h->client) 467 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO);
467 { 468 h->client = NULL;
468 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); 469 }
469 h->client = NULL;
470 }
471#if DEBUG_STATISTICS 470#if DEBUG_STATISTICS
472 LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 471 LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
473 "Error receiving statistics from service, is the service running?\n"); 472 "Error receiving statistics from service, is the service running?\n");
474#endif 473#endif
475 finish (h, GNUNET_SYSERR); 474 finish (h, GNUNET_SYSERR);
476 return; 475 return;
477 } 476 }
478 switch (ntohs (msg->type)) 477 switch (ntohs (msg->type))
478 {
479 case GNUNET_MESSAGE_TYPE_STATISTICS_END:
480#if DEBUG_STATISTICS
481 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received end of statistics marker\n");
482#endif
483 h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
484 if (h->watches_size > 0)
479 { 485 {
480 case GNUNET_MESSAGE_TYPE_STATISTICS_END: 486 GNUNET_CLIENT_receive (h->client, &receive_stats, h,
487 GNUNET_TIME_UNIT_FOREVER_REL);
488 }
489 else
490 {
491 h->receiving = GNUNET_NO;
492 }
493 finish (h, GNUNET_OK);
494 return;
495 case GNUNET_MESSAGE_TYPE_STATISTICS_VALUE:
496 if (GNUNET_OK == process_message (h, msg))
497 {
498 /* finally, look for more! */
481#if DEBUG_STATISTICS 499#if DEBUG_STATISTICS
482 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received end of statistics marker\n"); 500 LOG (GNUNET_ERROR_TYPE_DEBUG,
501 "Processing VALUE done, now reading more\n");
483#endif 502#endif
503 GNUNET_CLIENT_receive (h->client, &receive_stats, h,
504 GNUNET_TIME_absolute_get_remaining (h->
505 current->timeout));
484 h->backoff = GNUNET_TIME_UNIT_MILLISECONDS; 506 h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
485 if (h->watches_size > 0)
486 {
487 GNUNET_CLIENT_receive (h->client, &receive_stats, h,
488 GNUNET_TIME_UNIT_FOREVER_REL);
489 }
490 else
491 {
492 h->receiving = GNUNET_NO;
493 }
494 finish (h, GNUNET_OK);
495 return; 507 return;
496 case GNUNET_MESSAGE_TYPE_STATISTICS_VALUE:
497 if (GNUNET_OK == process_message (h, msg))
498 {
499 /* finally, look for more! */
500#if DEBUG_STATISTICS
501 LOG (GNUNET_ERROR_TYPE_DEBUG,
502 "Processing VALUE done, now reading more\n");
503#endif
504 GNUNET_CLIENT_receive (h->client, &receive_stats, h,
505 GNUNET_TIME_absolute_get_remaining
506 (h->current->timeout));
507 h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
508 return;
509 }
510 GNUNET_break (0);
511 break;
512 case GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE:
513 if (GNUNET_OK == process_watch_value (h, msg))
514 {
515 h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
516 GNUNET_assert (h->watches_size > 0);
517 GNUNET_CLIENT_receive (h->client, &receive_stats, h,
518 GNUNET_TIME_UNIT_FOREVER_REL);
519 return;
520 }
521 GNUNET_break (0);
522 break;
523 default:
524 GNUNET_break (0);
525 break;
526 } 508 }
527 if (NULL != h->client) 509 GNUNET_break (0);
510 break;
511 case GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE:
512 if (GNUNET_OK == process_watch_value (h, msg))
528 { 513 {
529 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); 514 h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
530 h->client = NULL; 515 GNUNET_assert (h->watches_size > 0);
516 GNUNET_CLIENT_receive (h->client, &receive_stats, h,
517 GNUNET_TIME_UNIT_FOREVER_REL);
518 return;
531 } 519 }
520 GNUNET_break (0);
521 break;
522 default:
523 GNUNET_break (0);
524 break;
525 }
526 if (NULL != h->client)
527 {
528 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO);
529 h->client = NULL;
530 }
532 finish (h, GNUNET_SYSERR); 531 finish (h, GNUNET_SYSERR);
533} 532}
534 533
@@ -546,15 +545,15 @@ transmit_get (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
546 uint16_t msize; 545 uint16_t msize;
547 546
548 if (buf == NULL) 547 if (buf == NULL)
549 { 548 {
550 /* timeout / error */ 549 /* timeout / error */
551#if DEBUG_STATISTICS 550#if DEBUG_STATISTICS
552 LOG (GNUNET_ERROR_TYPE_DEBUG, 551 LOG (GNUNET_ERROR_TYPE_DEBUG,
553 "Transmission of request for statistics failed!\n"); 552 "Transmission of request for statistics failed!\n");
554#endif 553#endif
555 finish (handle, GNUNET_SYSERR); 554 finish (handle, GNUNET_SYSERR);
556 return 0; 555 return 0;
557 } 556 }
558 slen1 = strlen (handle->current->subsystem) + 1; 557 slen1 = strlen (handle->current->subsystem) + 1;
559 slen2 = strlen (handle->current->name) + 1; 558 slen2 = strlen (handle->current->name) + 1;
560 msize = slen1 + slen2 + sizeof (struct GNUNET_MessageHeader); 559 msize = slen1 + slen2 + sizeof (struct GNUNET_MessageHeader);
@@ -563,20 +562,20 @@ transmit_get (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
563 hdr->size = htons (msize); 562 hdr->size = htons (msize);
564 hdr->type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_GET); 563 hdr->type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_GET);
565 GNUNET_assert (slen1 + slen2 == 564 GNUNET_assert (slen1 + slen2 ==
566 GNUNET_STRINGS_buffer_fill ((char *) &hdr[1], slen1 + slen2, 565 GNUNET_STRINGS_buffer_fill ((char *) &hdr[1], slen1 + slen2, 2,
567 2, handle->current->subsystem, 566 handle->current->subsystem,
568 handle->current->name)); 567 handle->current->name));
569 if (!handle->receiving) 568 if (!handle->receiving)
570 { 569 {
571#if DEBUG_STATISTICS 570#if DEBUG_STATISTICS
572 LOG (GNUNET_ERROR_TYPE_DEBUG, 571 LOG (GNUNET_ERROR_TYPE_DEBUG,
573 "Transmission of GET done, now reading response\n"); 572 "Transmission of GET done, now reading response\n");
574#endif 573#endif
575 handle->receiving = GNUNET_YES; 574 handle->receiving = GNUNET_YES;
576 GNUNET_CLIENT_receive (handle->client, &receive_stats, handle, 575 GNUNET_CLIENT_receive (handle->client, &receive_stats, handle,
577 GNUNET_TIME_absolute_get_remaining 576 GNUNET_TIME_absolute_get_remaining (handle->
578 (handle->current->timeout)); 577 current->timeout));
579 } 578 }
580 return msize; 579 return msize;
581} 580}
582 581
@@ -586,8 +585,7 @@ transmit_get (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
586 * the response). 585 * the response).
587 */ 586 */
588static size_t 587static size_t
589transmit_watch (struct GNUNET_STATISTICS_Handle *handle, size_t size, 588transmit_watch (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
590 void *buf)
591{ 589{
592 struct GNUNET_MessageHeader *hdr; 590 struct GNUNET_MessageHeader *hdr;
593 size_t slen1; 591 size_t slen1;
@@ -595,15 +593,15 @@ transmit_watch (struct GNUNET_STATISTICS_Handle *handle, size_t size,
595 uint16_t msize; 593 uint16_t msize;
596 594
597 if (buf == NULL) 595 if (buf == NULL)
598 { 596 {
599 /* timeout / error */ 597 /* timeout / error */
600#if DEBUG_STATISTICS 598#if DEBUG_STATISTICS
601 LOG (GNUNET_ERROR_TYPE_DEBUG, 599 LOG (GNUNET_ERROR_TYPE_DEBUG,
602 "Transmission of request for statistics failed!\n"); 600 "Transmission of request for statistics failed!\n");
603#endif 601#endif
604 finish (handle, GNUNET_SYSERR); 602 finish (handle, GNUNET_SYSERR);
605 return 0; 603 return 0;
606 } 604 }
607#if DEBUG_STATISTICS 605#if DEBUG_STATISTICS
608 LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting watch request for `%s'\n", 606 LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting watch request for `%s'\n",
609 handle->current->name); 607 handle->current->name);
@@ -616,15 +614,15 @@ transmit_watch (struct GNUNET_STATISTICS_Handle *handle, size_t size,
616 hdr->size = htons (msize); 614 hdr->size = htons (msize);
617 hdr->type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_WATCH); 615 hdr->type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_WATCH);
618 GNUNET_assert (slen1 + slen2 == 616 GNUNET_assert (slen1 + slen2 ==
619 GNUNET_STRINGS_buffer_fill ((char *) &hdr[1], slen1 + slen2, 617 GNUNET_STRINGS_buffer_fill ((char *) &hdr[1], slen1 + slen2, 2,
620 2, handle->current->subsystem, 618 handle->current->subsystem,
621 handle->current->name)); 619 handle->current->name));
622 if (GNUNET_YES != handle->receiving) 620 if (GNUNET_YES != handle->receiving)
623 { 621 {
624 handle->receiving = GNUNET_YES; 622 handle->receiving = GNUNET_YES;
625 GNUNET_CLIENT_receive (handle->client, &receive_stats, handle, 623 GNUNET_CLIENT_receive (handle->client, &receive_stats, handle,
626 GNUNET_TIME_UNIT_FOREVER_REL); 624 GNUNET_TIME_UNIT_FOREVER_REL);
627 } 625 }
628 finish (handle, GNUNET_OK); 626 finish (handle, GNUNET_OK);
629 return msize; 627 return msize;
630} 628}
@@ -642,20 +640,20 @@ transmit_set (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
642 size_t nsize; 640 size_t nsize;
643 641
644 if (NULL == buf) 642 if (NULL == buf)
645 { 643 {
646 finish (handle, GNUNET_SYSERR); 644 finish (handle, GNUNET_SYSERR);
647 return 0; 645 return 0;
648 } 646 }
649 647
650 slen = strlen (handle->current->subsystem) + 1; 648 slen = strlen (handle->current->subsystem) + 1;
651 nlen = strlen (handle->current->name) + 1; 649 nlen = strlen (handle->current->name) + 1;
652 nsize = sizeof (struct GNUNET_STATISTICS_SetMessage) + slen + nlen; 650 nsize = sizeof (struct GNUNET_STATISTICS_SetMessage) + slen + nlen;
653 if (size < nsize) 651 if (size < nsize)
654 { 652 {
655 GNUNET_break (0); 653 GNUNET_break (0);
656 finish (handle, GNUNET_SYSERR); 654 finish (handle, GNUNET_SYSERR);
657 return 0; 655 return 0;
658 } 656 }
659 r = buf; 657 r = buf;
660 r->header.size = htons (nsize); 658 r->header.size = htons (nsize);
661 r->header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_SET); 659 r->header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_SET);
@@ -666,9 +664,9 @@ transmit_set (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
666 if (handle->current->type == ACTION_UPDATE) 664 if (handle->current->type == ACTION_UPDATE)
667 r->flags |= htonl (GNUNET_STATISTICS_SETFLAG_RELATIVE); 665 r->flags |= htonl (GNUNET_STATISTICS_SETFLAG_RELATIVE);
668 GNUNET_assert (slen + nlen == 666 GNUNET_assert (slen + nlen ==
669 GNUNET_STRINGS_buffer_fill ((char *) &r[1], slen + nlen, 2, 667 GNUNET_STRINGS_buffer_fill ((char *) &r[1], slen + nlen, 2,
670 handle->current->subsystem, 668 handle->current->subsystem,
671 handle->current->name)); 669 handle->current->name));
672 finish (handle, GNUNET_OK); 670 finish (handle, GNUNET_OK);
673 return nsize; 671 return nsize;
674} 672}
@@ -682,22 +680,22 @@ transmit_action (void *cls, size_t size, void *buf)
682 680
683 handle->th = NULL; 681 handle->th = NULL;
684 switch (handle->current->type) 682 switch (handle->current->type)
685 { 683 {
686 case ACTION_GET: 684 case ACTION_GET:
687 ret = transmit_get (handle, size, buf); 685 ret = transmit_get (handle, size, buf);
688 break; 686 break;
689 case ACTION_SET: 687 case ACTION_SET:
690 case ACTION_UPDATE: 688 case ACTION_UPDATE:
691 ret = transmit_set (handle, size, buf); 689 ret = transmit_set (handle, size, buf);
692 break; 690 break;
693 case ACTION_WATCH: 691 case ACTION_WATCH:
694 ret = transmit_watch (handle, size, buf); 692 ret = transmit_watch (handle, size, buf);
695 break; 693 break;
696 default: 694 default:
697 ret = 0; 695 ret = 0;
698 GNUNET_break (0); 696 GNUNET_break (0);
699 break; 697 break;
700 } 698 }
701 return ret; 699 return ret;
702} 700}
703 701
@@ -711,7 +709,7 @@ transmit_action (void *cls, size_t size, void *buf)
711 */ 709 */
712struct GNUNET_STATISTICS_Handle * 710struct GNUNET_STATISTICS_Handle *
713GNUNET_STATISTICS_create (const char *subsystem, 711GNUNET_STATISTICS_create (const char *subsystem,
714 const struct GNUNET_CONFIGURATION_Handle *cfg) 712 const struct GNUNET_CONFIGURATION_Handle *cfg)
715{ 713{
716 struct GNUNET_STATISTICS_Handle *ret; 714 struct GNUNET_STATISTICS_Handle *ret;
717 715
@@ -722,11 +720,11 @@ GNUNET_STATISTICS_create (const char *subsystem,
722 ret->subsystem = GNUNET_strdup (subsystem); 720 ret->subsystem = GNUNET_strdup (subsystem);
723 ret->backoff = GNUNET_TIME_UNIT_MILLISECONDS; 721 ret->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
724 if (GNUNET_YES != try_connect (ret)) 722 if (GNUNET_YES != try_connect (ret))
725 { 723 {
726 GNUNET_free (ret->subsystem); 724 GNUNET_free (ret->subsystem);
727 GNUNET_free (ret); 725 GNUNET_free (ret);
728 return NULL; 726 return NULL;
729 } 727 }
730 return ret; 728 return ret;
731} 729}
732 730
@@ -753,83 +751,83 @@ GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h, int sync_first)
753 if (GNUNET_SCHEDULER_NO_TASK != h->backoff_task) 751 if (GNUNET_SCHEDULER_NO_TASK != h->backoff_task)
754 GNUNET_SCHEDULER_cancel (h->backoff_task); 752 GNUNET_SCHEDULER_cancel (h->backoff_task);
755 if (sync_first) 753 if (sync_first)
754 {
755 if (h->current != NULL)
756 { 756 {
757 if (h->current != NULL) 757 if (h->current->type == ACTION_GET)
758 { 758 {
759 if (h->current->type == ACTION_GET) 759 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
760 { 760 h->th = NULL;
761 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); 761 free_action_item (h->current);
762 h->th = NULL; 762 h->current = NULL;
763 free_action_item (h->current); 763 }
764 h->current = NULL;
765 }
766 }
767 pos = h->action_head;
768 prev = NULL;
769 while (pos != NULL)
770 {
771 next = pos->next;
772 if (pos->type == ACTION_GET)
773 {
774 if (prev == NULL)
775 h->action_head = next;
776 else
777 prev->next = next;
778 free_action_item (pos);
779 }
780 else
781 {
782 prev = pos;
783 }
784 pos = next;
785 }
786 h->action_tail = prev;
787 if (h->current == NULL)
788 {
789 h->current = h->action_head;
790 if (h->action_head != NULL)
791 {
792 h->action_head = h->action_head->next;
793 if (h->action_head == NULL)
794 h->action_tail = NULL;
795 }
796 }
797 h->do_destroy = GNUNET_YES;
798 if ((h->current != NULL) && (h->th == NULL))
799 {
800 timeout = GNUNET_TIME_absolute_get_remaining (h->current->timeout);
801 h->th =
802 GNUNET_CLIENT_notify_transmit_ready (h->client, h->current->msize,
803 timeout, GNUNET_YES,
804 &transmit_action, h);
805 GNUNET_assert (NULL != h->th);
806 }
807 if (h->th != NULL)
808 return;
809 } 764 }
810 if (NULL != h->th) 765 pos = h->action_head;
766 prev = NULL;
767 while (pos != NULL)
811 { 768 {
812 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); 769 next = pos->next;
813 h->th = NULL; 770 if (pos->type == ACTION_GET)
771 {
772 if (prev == NULL)
773 h->action_head = next;
774 else
775 prev->next = next;
776 free_action_item (pos);
777 }
778 else
779 {
780 prev = pos;
781 }
782 pos = next;
814 } 783 }
815 if (h->current != NULL) 784 h->action_tail = prev;
816 free_action_item (h->current); 785 if (h->current == NULL)
817 while (NULL != (pos = h->action_head))
818 { 786 {
819 h->action_head = pos->next; 787 h->current = h->action_head;
820 free_action_item (pos); 788 if (h->action_head != NULL)
789 {
790 h->action_head = h->action_head->next;
791 if (h->action_head == NULL)
792 h->action_tail = NULL;
793 }
821 } 794 }
822 if (h->client != NULL) 795 h->do_destroy = GNUNET_YES;
796 if ((h->current != NULL) && (h->th == NULL))
823 { 797 {
824 GNUNET_CLIENT_disconnect (h->client, GNUNET_YES); 798 timeout = GNUNET_TIME_absolute_get_remaining (h->current->timeout);
825 h->client = NULL; 799 h->th =
800 GNUNET_CLIENT_notify_transmit_ready (h->client, h->current->msize,
801 timeout, GNUNET_YES,
802 &transmit_action, h);
803 GNUNET_assert (NULL != h->th);
826 } 804 }
805 if (h->th != NULL)
806 return;
807 }
808 if (NULL != h->th)
809 {
810 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
811 h->th = NULL;
812 }
813 if (h->current != NULL)
814 free_action_item (h->current);
815 while (NULL != (pos = h->action_head))
816 {
817 h->action_head = pos->next;
818 free_action_item (pos);
819 }
820 if (h->client != NULL)
821 {
822 GNUNET_CLIENT_disconnect (h->client, GNUNET_YES);
823 h->client = NULL;
824 }
827 for (i = 0; i < h->watches_size; i++) 825 for (i = 0; i < h->watches_size; i++)
828 { 826 {
829 GNUNET_free (h->watches[i]->subsystem); 827 GNUNET_free (h->watches[i]->subsystem);
830 GNUNET_free (h->watches[i]->name); 828 GNUNET_free (h->watches[i]->name);
831 GNUNET_free (h->watches[i]); 829 GNUNET_free (h->watches[i]);
832 } 830 }
833 GNUNET_array_grow (h->watches, h->watches_size, 0); 831 GNUNET_array_grow (h->watches, h->watches_size, 0);
834 GNUNET_free (h->subsystem); 832 GNUNET_free (h->subsystem);
835 GNUNET_free (h); 833 GNUNET_free (h);
@@ -855,43 +853,42 @@ schedule_action (struct GNUNET_STATISTICS_Handle *h)
855 struct GNUNET_TIME_Relative timeout; 853 struct GNUNET_TIME_Relative timeout;
856 854
857 if (h->current != NULL) 855 if (h->current != NULL)
858 return; /* action already pending */ 856 return; /* action already pending */
859 if (GNUNET_YES != try_connect (h)) 857 if (GNUNET_YES != try_connect (h))
860 { 858 {
861 h->backoff_task = 859 h->backoff_task =
862 GNUNET_SCHEDULER_add_delayed (h->backoff, &finish_task, h); 860 GNUNET_SCHEDULER_add_delayed (h->backoff, &finish_task, h);
863 h->backoff = GNUNET_TIME_relative_multiply (h->backoff, 2); 861 h->backoff = GNUNET_TIME_relative_multiply (h->backoff, 2);
864 h->backoff = 862 h->backoff =
865 GNUNET_TIME_relative_min (h->backoff, 863 GNUNET_TIME_relative_min (h->backoff, GNUNET_CONSTANTS_SERVICE_TIMEOUT);
866 GNUNET_CONSTANTS_SERVICE_TIMEOUT); 864 return;
867 return; 865 }
868 }
869 866
870 /* schedule next action */ 867 /* schedule next action */
871 h->current = h->action_head; 868 h->current = h->action_head;
872 if (NULL == h->current) 869 if (NULL == h->current)
870 {
871 if (h->do_destroy)
873 { 872 {
874 if (h->do_destroy) 873 h->do_destroy = GNUNET_NO;
875 { 874 GNUNET_STATISTICS_destroy (h, GNUNET_YES);
876 h->do_destroy = GNUNET_NO;
877 GNUNET_STATISTICS_destroy (h, GNUNET_YES);
878 }
879 return;
880 } 875 }
876 return;
877 }
881 GNUNET_CONTAINER_DLL_remove (h->action_head, h->action_tail, h->current); 878 GNUNET_CONTAINER_DLL_remove (h->action_head, h->action_tail, h->current);
882 timeout = GNUNET_TIME_absolute_get_remaining (h->current->timeout); 879 timeout = GNUNET_TIME_absolute_get_remaining (h->current->timeout);
883 if (NULL == 880 if (NULL ==
884 (h->th = 881 (h->th =
885 GNUNET_CLIENT_notify_transmit_ready (h->client, h->current->msize, 882 GNUNET_CLIENT_notify_transmit_ready (h->client, h->current->msize,
886 timeout, GNUNET_YES, 883 timeout, GNUNET_YES,
887 &transmit_action, h))) 884 &transmit_action, h)))
888 { 885 {
889#if DEBUG_STATISTICS 886#if DEBUG_STATISTICS
890 LOG (GNUNET_ERROR_TYPE_DEBUG, 887 LOG (GNUNET_ERROR_TYPE_DEBUG,
891 "Failed to transmit request to statistics service.\n"); 888 "Failed to transmit request to statistics service.\n");
892#endif 889#endif
893 finish (h, GNUNET_SYSERR); 890 finish (h, GNUNET_SYSERR);
894 } 891 }
895} 892}
896 893
897 894
@@ -910,10 +907,10 @@ schedule_action (struct GNUNET_STATISTICS_Handle *h)
910 */ 907 */
911struct GNUNET_STATISTICS_GetHandle * 908struct GNUNET_STATISTICS_GetHandle *
912GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle, 909GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle,
913 const char *subsystem, const char *name, 910 const char *subsystem, const char *name,
914 struct GNUNET_TIME_Relative timeout, 911 struct GNUNET_TIME_Relative timeout,
915 GNUNET_STATISTICS_Callback cont, 912 GNUNET_STATISTICS_Callback cont,
916 GNUNET_STATISTICS_Iterator proc, void *cls) 913 GNUNET_STATISTICS_Iterator proc, void *cls)
917{ 914{
918 size_t slen1; 915 size_t slen1;
919 size_t slen2; 916 size_t slen2;
@@ -923,14 +920,14 @@ GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle,
923 GNUNET_assert (proc != NULL); 920 GNUNET_assert (proc != NULL);
924 GNUNET_assert (GNUNET_NO == handle->do_destroy); 921 GNUNET_assert (GNUNET_NO == handle->do_destroy);
925 if (GNUNET_YES != try_connect (handle)) 922 if (GNUNET_YES != try_connect (handle))
926 { 923 {
927#if DEBUG_STATISTICS 924#if DEBUG_STATISTICS
928 LOG (GNUNET_ERROR_TYPE_DEBUG, 925 LOG (GNUNET_ERROR_TYPE_DEBUG,
929 "Failed to connect to statistics service, can not get value `%s:%s'.\n", 926 "Failed to connect to statistics service, can not get value `%s:%s'.\n",
930 strlen (subsystem) ? subsystem : "*", strlen (name) ? name : "*"); 927 strlen (subsystem) ? subsystem : "*", strlen (name) ? name : "*");
931#endif 928#endif
932 return NULL; 929 return NULL;
933 } 930 }
934 if (subsystem == NULL) 931 if (subsystem == NULL)
935 subsystem = ""; 932 subsystem = "";
936 if (name == NULL) 933 if (name == NULL)
@@ -938,7 +935,7 @@ GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle,
938 slen1 = strlen (subsystem) + 1; 935 slen1 = strlen (subsystem) + 1;
939 slen2 = strlen (name) + 1; 936 slen2 = strlen (name) + 1;
940 GNUNET_assert (slen1 + slen2 + sizeof (struct GNUNET_MessageHeader) < 937 GNUNET_assert (slen1 + slen2 + sizeof (struct GNUNET_MessageHeader) <
941 GNUNET_SERVER_MAX_MESSAGE_SIZE); 938 GNUNET_SERVER_MAX_MESSAGE_SIZE);
942 ai = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_GetHandle)); 939 ai = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_GetHandle));
943 ai->sh = handle; 940 ai->sh = handle;
944 ai->subsystem = GNUNET_strdup (subsystem); 941 ai->subsystem = GNUNET_strdup (subsystem);
@@ -964,17 +961,16 @@ void
964GNUNET_STATISTICS_get_cancel (struct GNUNET_STATISTICS_GetHandle *gh) 961GNUNET_STATISTICS_get_cancel (struct GNUNET_STATISTICS_GetHandle *gh)
965{ 962{
966 if (gh->sh->current == gh) 963 if (gh->sh->current == gh)
967 { 964 {
968 gh->aborted = GNUNET_YES; 965 gh->aborted = GNUNET_YES;
969 } 966 }
970 else 967 else
971 { 968 {
972 GNUNET_CONTAINER_DLL_remove (gh->sh->action_head, gh->sh->action_tail, 969 GNUNET_CONTAINER_DLL_remove (gh->sh->action_head, gh->sh->action_tail, gh);
973 gh); 970 GNUNET_free (gh->name);
974 GNUNET_free (gh->name); 971 GNUNET_free (gh->subsystem);
975 GNUNET_free (gh->subsystem); 972 GNUNET_free (gh);
976 GNUNET_free (gh); 973 }
977 }
978} 974}
979 975
980 976
@@ -992,8 +988,8 @@ GNUNET_STATISTICS_get_cancel (struct GNUNET_STATISTICS_GetHandle *gh)
992 */ 988 */
993int 989int
994GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle, 990GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle,
995 const char *subsystem, const char *name, 991 const char *subsystem, const char *name,
996 GNUNET_STATISTICS_Iterator proc, void *proc_cls) 992 GNUNET_STATISTICS_Iterator proc, void *proc_cls)
997{ 993{
998 struct GNUNET_STATISTICS_WatchEntry *w; 994 struct GNUNET_STATISTICS_WatchEntry *w;
999 995
@@ -1012,7 +1008,7 @@ GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle,
1012 1008
1013static void 1009static void
1014add_setter_action (struct GNUNET_STATISTICS_Handle *h, const char *name, 1010add_setter_action (struct GNUNET_STATISTICS_Handle *h, const char *name,
1015 int make_persistent, uint64_t value, enum ActionType type) 1011 int make_persistent, uint64_t value, enum ActionType type)
1016{ 1012{
1017 struct GNUNET_STATISTICS_GetHandle *ai; 1013 struct GNUNET_STATISTICS_GetHandle *ai;
1018 size_t slen; 1014 size_t slen;
@@ -1028,59 +1024,58 @@ add_setter_action (struct GNUNET_STATISTICS_Handle *h, const char *name,
1028 nlen = strlen (name) + 1; 1024 nlen = strlen (name) + 1;
1029 nsize = sizeof (struct GNUNET_STATISTICS_SetMessage) + slen + nlen; 1025 nsize = sizeof (struct GNUNET_STATISTICS_SetMessage) + slen + nlen;
1030 if (nsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1026 if (nsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1031 { 1027 {
1032 GNUNET_break (0); 1028 GNUNET_break (0);
1033 return; 1029 return;
1034 } 1030 }
1035 ai = h->action_head; 1031 ai = h->action_head;
1036 while (ai != NULL) 1032 while (ai != NULL)
1033 {
1034 if ((0 == strcmp (ai->subsystem, h->subsystem)) &&
1035 (0 == strcmp (ai->name, name)) && ((ai->type == ACTION_UPDATE) ||
1036 (ai->type == ACTION_SET)))
1037 { 1037 {
1038 if ((0 == strcmp (ai->subsystem, h->subsystem)) && 1038 if (ai->type == ACTION_SET)
1039 (0 == strcmp (ai->name, name)) && ((ai->type == ACTION_UPDATE) || 1039 {
1040 (ai->type == ACTION_SET))) 1040 if (type == ACTION_UPDATE)
1041 { 1041 {
1042 if (ai->type == ACTION_SET) 1042 delta = (int64_t) value;
1043 { 1043 if (delta > 0)
1044 if (type == ACTION_UPDATE) 1044 {
1045 { 1045 ai->value += delta;
1046 delta = (int64_t) value; 1046 }
1047 if (delta > 0) 1047 else
1048 { 1048 {
1049 ai->value += delta; 1049 if (ai->value < -delta)
1050 } 1050 ai->value = 0;
1051 else 1051 else
1052 { 1052 ai->value += delta;
1053 if (ai->value < -delta) 1053 }
1054 ai->value = 0; 1054 }
1055 else 1055 else
1056 ai->value += delta; 1056 {
1057 } 1057 ai->value = value;
1058 } 1058 }
1059 else 1059 }
1060 { 1060 else
1061 ai->value = value; 1061 {
1062 } 1062 if (type == ACTION_UPDATE)
1063 } 1063 {
1064 else 1064 delta = (int64_t) value;
1065 { 1065 ai->value += delta;
1066 if (type == ACTION_UPDATE) 1066 }
1067 { 1067 else
1068 delta = (int64_t) value; 1068 {
1069 ai->value += delta; 1069 ai->value = value;
1070 } 1070 ai->type = type;
1071 else 1071 }
1072 { 1072 }
1073 ai->value = value; 1073 ai->timeout = GNUNET_TIME_relative_to_absolute (SET_TRANSMIT_TIMEOUT);
1074 ai->type = type; 1074 ai->make_persistent = make_persistent;
1075 } 1075 return;
1076 }
1077 ai->timeout =
1078 GNUNET_TIME_relative_to_absolute (SET_TRANSMIT_TIMEOUT);
1079 ai->make_persistent = make_persistent;
1080 return;
1081 }
1082 ai = ai->next;
1083 } 1076 }
1077 ai = ai->next;
1078 }
1084 ai = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_GetHandle)); 1079 ai = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_GetHandle));
1085 ai->sh = h; 1080 ai->sh = h;
1086 ai->subsystem = GNUNET_strdup (h->subsystem); 1081 ai->subsystem = GNUNET_strdup (h->subsystem);
@@ -1105,7 +1100,7 @@ add_setter_action (struct GNUNET_STATISTICS_Handle *h, const char *name,
1105 */ 1100 */
1106void 1101void
1107GNUNET_STATISTICS_set (struct GNUNET_STATISTICS_Handle *handle, 1102GNUNET_STATISTICS_set (struct GNUNET_STATISTICS_Handle *handle,
1108 const char *name, uint64_t value, int make_persistent) 1103 const char *name, uint64_t value, int make_persistent)
1109{ 1104{
1110 if (handle == NULL) 1105 if (handle == NULL)
1111 return; 1106 return;
@@ -1125,8 +1120,7 @@ GNUNET_STATISTICS_set (struct GNUNET_STATISTICS_Handle *handle,
1125 */ 1120 */
1126void 1121void
1127GNUNET_STATISTICS_update (struct GNUNET_STATISTICS_Handle *handle, 1122GNUNET_STATISTICS_update (struct GNUNET_STATISTICS_Handle *handle,
1128 const char *name, int64_t delta, 1123 const char *name, int64_t delta, int make_persistent)
1129 int make_persistent)
1130{ 1124{
1131 if (handle == NULL) 1125 if (handle == NULL)
1132 return; 1126 return;
@@ -1134,7 +1128,7 @@ GNUNET_STATISTICS_update (struct GNUNET_STATISTICS_Handle *handle,
1134 return; 1128 return;
1135 GNUNET_assert (GNUNET_NO == handle->do_destroy); 1129 GNUNET_assert (GNUNET_NO == handle->do_destroy);
1136 add_setter_action (handle, name, make_persistent, (uint64_t) delta, 1130 add_setter_action (handle, name, make_persistent, (uint64_t) delta,
1137 ACTION_UPDATE); 1131 ACTION_UPDATE);
1138} 1132}
1139 1133
1140 1134