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.c747
1 files changed, 359 insertions, 388 deletions
diff --git a/src/statistics/statistics_api.c b/src/statistics/statistics_api.c
index e7cc73832..a76f83db1 100644
--- a/src/statistics/statistics_api.c
+++ b/src/statistics/statistics_api.c
@@ -58,7 +58,7 @@ enum ActionType
58 */ 58 */
59struct GNUNET_STATISTICS_WatchEntry 59struct GNUNET_STATISTICS_WatchEntry
60{ 60{
61 61
62 /** 62 /**
63 * What subsystem is this action about? (never NULL) 63 * What subsystem is this action about? (never NULL)
64 */ 64 */
@@ -102,7 +102,7 @@ struct GNUNET_STATISTICS_GetHandle
102 * Main statistics handle. 102 * Main statistics handle.
103 */ 103 */
104 struct GNUNET_STATISTICS_Handle *sh; 104 struct GNUNET_STATISTICS_Handle *sh;
105 105
106 /** 106 /**
107 * What subsystem is this action about? (can be NULL) 107 * What subsystem is this action about? (can be NULL)
108 */ 108 */
@@ -249,17 +249,15 @@ static void schedule_action (struct GNUNET_STATISTICS_Handle *h);
249 * 249 *
250 * @return GNUNET_YES on success, GNUNET_NO on failure. 250 * @return GNUNET_YES on success, GNUNET_NO on failure.
251 */ 251 */
252static int 252static int try_connect (struct GNUNET_STATISTICS_Handle *ret);
253try_connect (struct GNUNET_STATISTICS_Handle *ret);
254 253
255 254
256static void 255static void
257insert_ai (struct GNUNET_STATISTICS_Handle *h, struct GNUNET_STATISTICS_GetHandle *ai) 256insert_ai (struct GNUNET_STATISTICS_Handle *h,
257 struct GNUNET_STATISTICS_GetHandle *ai)
258{ 258{
259 GNUNET_CONTAINER_DLL_insert_after (h->action_head, 259 GNUNET_CONTAINER_DLL_insert_after (h->action_head,
260 h->action_tail, 260 h->action_tail, h->action_tail, ai);
261 h->action_tail,
262 ai);
263 if (h->action_head == ai) 261 if (h->action_head == ai)
264 schedule_action (h); 262 schedule_action (h);
265} 263}
@@ -267,28 +265,28 @@ insert_ai (struct GNUNET_STATISTICS_Handle *h, struct GNUNET_STATISTICS_GetHandl
267 265
268static void 266static void
269schedule_watch_request (struct GNUNET_STATISTICS_Handle *h, 267schedule_watch_request (struct GNUNET_STATISTICS_Handle *h,
270 struct GNUNET_STATISTICS_WatchEntry *watch) 268 struct GNUNET_STATISTICS_WatchEntry *watch)
271{ 269{
272 270
273 struct GNUNET_STATISTICS_GetHandle *ai; 271 struct GNUNET_STATISTICS_GetHandle *ai;
274 size_t slen; 272 size_t slen;
275 size_t nlen; 273 size_t nlen;
276 size_t nsize; 274 size_t nsize;
277 275
278 GNUNET_assert (h != NULL); 276 GNUNET_assert (h != NULL);
279 if (GNUNET_YES != try_connect (h)) 277 if (GNUNET_YES != try_connect (h))
280 { 278 {
281 schedule_action (h); 279 schedule_action (h);
282 return; 280 return;
283 } 281 }
284 slen = strlen (watch->subsystem) + 1; 282 slen = strlen (watch->subsystem) + 1;
285 nlen = strlen (watch->name) + 1; 283 nlen = strlen (watch->name) + 1;
286 nsize = sizeof (struct GNUNET_MessageHeader) + slen + nlen; 284 nsize = sizeof (struct GNUNET_MessageHeader) + slen + nlen;
287 if (nsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 285 if (nsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
288 { 286 {
289 GNUNET_break (0); 287 GNUNET_break (0);
290 return; 288 return;
291 } 289 }
292 ai = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_GetHandle)); 290 ai = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_GetHandle));
293 ai->sh = h; 291 ai->sh = h;
294 ai->subsystem = GNUNET_strdup (watch->subsystem); 292 ai->subsystem = GNUNET_strdup (watch->subsystem);
@@ -311,15 +309,16 @@ static int
311try_connect (struct GNUNET_STATISTICS_Handle *ret) 309try_connect (struct GNUNET_STATISTICS_Handle *ret)
312{ 310{
313 unsigned int i; 311 unsigned int i;
312
314 if (ret->client != NULL) 313 if (ret->client != NULL)
315 return GNUNET_YES; 314 return GNUNET_YES;
316 ret->client = GNUNET_CLIENT_connect ("statistics", ret->cfg); 315 ret->client = GNUNET_CLIENT_connect ("statistics", ret->cfg);
317 if (ret->client != NULL) 316 if (ret->client != NULL)
318 { 317 {
319 for (i=0;i<ret->watches_size;i++) 318 for (i = 0; i < ret->watches_size; i++)
320 schedule_watch_request (ret, ret->watches[i]); 319 schedule_watch_request (ret, ret->watches[i]);
321 return GNUNET_YES; 320 return GNUNET_YES;
322 } 321 }
323#if DEBUG_STATISTICS 322#if DEBUG_STATISTICS
324 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 323 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
325 _("Failed to connect to statistics service!\n")); 324 _("Failed to connect to statistics service!\n"));
@@ -347,14 +346,15 @@ static void
347finish (struct GNUNET_STATISTICS_Handle *h, int code) 346finish (struct GNUNET_STATISTICS_Handle *h, int code)
348{ 347{
349 struct GNUNET_STATISTICS_GetHandle *pos = h->current; 348 struct GNUNET_STATISTICS_GetHandle *pos = h->current;
349
350 h->current = NULL; 350 h->current = NULL;
351 schedule_action (h); 351 schedule_action (h);
352 if (pos != NULL) 352 if (pos != NULL)
353 { 353 {
354 if (pos->cont != NULL) 354 if (pos->cont != NULL)
355 pos->cont (pos->cls, code); 355 pos->cont (pos->cls, code);
356 free_action_item (pos); 356 free_action_item (pos);
357 } 357 }
358} 358}
359 359
360 360
@@ -373,27 +373,27 @@ process_message (struct GNUNET_STATISTICS_Handle *h,
373 uint16_t size; 373 uint16_t size;
374 374
375 if (h->current->aborted) 375 if (h->current->aborted)
376 { 376 {
377#if DEBUG_STATISTICS 377#if DEBUG_STATISTICS
378 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 378 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
379 "Iteration was aborted, ignoring VALUE\n"); 379 "Iteration was aborted, ignoring VALUE\n");
380#endif 380#endif
381 return GNUNET_OK; /* don't bother */ 381 return GNUNET_OK; /* don't bother */
382 } 382 }
383 size = ntohs (msg->size); 383 size = ntohs (msg->size);
384 if (size < sizeof (struct GNUNET_STATISTICS_ReplyMessage)) 384 if (size < sizeof (struct GNUNET_STATISTICS_ReplyMessage))
385 { 385 {
386 GNUNET_break (0); 386 GNUNET_break (0);
387 return GNUNET_SYSERR; 387 return GNUNET_SYSERR;
388 } 388 }
389 smsg = (const struct GNUNET_STATISTICS_ReplyMessage *) msg; 389 smsg = (const struct GNUNET_STATISTICS_ReplyMessage *) msg;
390 size -= sizeof (struct GNUNET_STATISTICS_ReplyMessage); 390 size -= sizeof (struct GNUNET_STATISTICS_ReplyMessage);
391 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &smsg[1], 391 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &smsg[1],
392 size, 2, &service, &name)) 392 size, 2, &service, &name))
393 { 393 {
394 GNUNET_break (0); 394 GNUNET_break (0);
395 return GNUNET_SYSERR; 395 return GNUNET_SYSERR;
396 } 396 }
397#if DEBUG_STATISTICS 397#if DEBUG_STATISTICS
398 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 398 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
399 "Received valid statistic on `%s:%s': %llu\n", 399 "Received valid statistic on `%s:%s': %llu\n",
@@ -401,55 +401,52 @@ process_message (struct GNUNET_STATISTICS_Handle *h,
401#endif 401#endif
402 if (GNUNET_OK != 402 if (GNUNET_OK !=
403 h->current->proc (h->current->cls, 403 h->current->proc (h->current->cls,
404 service, 404 service,
405 name, 405 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 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 411 GNUNET_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 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 417 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "VALUE processed successfully\n");
418 "VALUE processed successfully\n"); 418#endif
419#endif
420 return GNUNET_OK; 419 return GNUNET_OK;
421} 420}
422 421
423 422
424static int 423static int
425process_watch_value (struct GNUNET_STATISTICS_Handle *h, 424process_watch_value (struct GNUNET_STATISTICS_Handle *h,
426 const struct GNUNET_MessageHeader *msg) 425 const struct GNUNET_MessageHeader *msg)
427{ 426{
428 const struct GNUNET_STATISTICS_WatchValueMessage *wvm; 427 const struct GNUNET_STATISTICS_WatchValueMessage *wvm;
429 struct GNUNET_STATISTICS_WatchEntry *w; 428 struct GNUNET_STATISTICS_WatchEntry *w;
430 uint32_t wid; 429 uint32_t wid;
431 430
432 if (sizeof(struct GNUNET_STATISTICS_WatchValueMessage) != 431 if (sizeof (struct GNUNET_STATISTICS_WatchValueMessage) != ntohs (msg->size))
433 ntohs (msg->size)) 432 {
434 { 433 GNUNET_break (0);
435 GNUNET_break (0); 434 return GNUNET_SYSERR;
436 return GNUNET_SYSERR; 435 }
437 } 436 wvm = (const struct GNUNET_STATISTICS_WatchValueMessage *) msg;
438 wvm = (const struct GNUNET_STATISTICS_WatchValueMessage *)msg;
439 GNUNET_break (0 == ntohl (wvm->reserved)); 437 GNUNET_break (0 == ntohl (wvm->reserved));
440 wid = ntohl (wvm->wid); 438 wid = ntohl (wvm->wid);
441 if (wid >= h->watches_size) 439 if (wid >= h->watches_size)
442 { 440 {
443 GNUNET_break (0); 441 GNUNET_break (0);
444 return GNUNET_SYSERR; 442 return GNUNET_SYSERR;
445 } 443 }
446 w = h->watches[wid]; 444 w = h->watches[wid];
447 (void) w->proc (w->proc_cls, 445 (void) w->proc (w->proc_cls,
448 w->subsystem, 446 w->subsystem,
449 w->name, 447 w->name,
450 GNUNET_ntohll (wvm->value), 448 GNUNET_ntohll (wvm->value),
451 0 != 449 0 != (ntohl (wvm->flags) & GNUNET_STATISTICS_PERSIST_BIT));
452 (ntohl (wvm->flags) & GNUNET_STATISTICS_PERSIST_BIT));
453 return GNUNET_OK; 450 return GNUNET_OK;
454} 451}
455 452
@@ -466,82 +463,75 @@ receive_stats (void *cls, const struct GNUNET_MessageHeader *msg)
466 struct GNUNET_STATISTICS_Handle *h = cls; 463 struct GNUNET_STATISTICS_Handle *h = cls;
467 464
468 if (msg == NULL) 465 if (msg == NULL)
466 {
467 if (NULL != h->client)
469 { 468 {
470 if (NULL != h->client) 469 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO);
471 { 470 h->client = NULL;
472 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); 471 }
473 h->client = NULL;
474 }
475#if DEBUG_STATISTICS 472#if DEBUG_STATISTICS
476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 473 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
477 "Error receiving statistics from service, is the service running?\n" ); 474 "Error receiving statistics from service, is the service running?\n");
478#endif 475#endif
479 finish (h, GNUNET_SYSERR); 476 finish (h, GNUNET_SYSERR);
480 return; 477 return;
481 } 478 }
482 switch (ntohs (msg->type)) 479 switch (ntohs (msg->type))
480 {
481 case GNUNET_MESSAGE_TYPE_STATISTICS_END:
482#if DEBUG_STATISTICS
483 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received end of statistics marker\n");
484#endif
485 h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
486 if (h->watches_size > 0)
483 { 487 {
484 case GNUNET_MESSAGE_TYPE_STATISTICS_END: 488 GNUNET_CLIENT_receive (h->client,
489 &receive_stats, h, GNUNET_TIME_UNIT_FOREVER_REL);
490 }
491 else
492 {
493 h->receiving = GNUNET_NO;
494 }
495 finish (h, GNUNET_OK);
496 return;
497 case GNUNET_MESSAGE_TYPE_STATISTICS_VALUE:
498 if (GNUNET_OK == process_message (h, msg))
499 {
500 /* finally, look for more! */
485#if DEBUG_STATISTICS 501#if DEBUG_STATISTICS
486 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 502 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
487 "Received end of statistics marker\n"); 503 "Processing VALUE done, now reading more\n");
488#endif 504#endif
505 GNUNET_CLIENT_receive (h->client,
506 &receive_stats,
507 h,
508 GNUNET_TIME_absolute_get_remaining
509 (h->current->timeout));
489 h->backoff = GNUNET_TIME_UNIT_MILLISECONDS; 510 h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
490 if (h->watches_size > 0)
491 {
492 GNUNET_CLIENT_receive (h->client,
493 &receive_stats,
494 h,
495 GNUNET_TIME_UNIT_FOREVER_REL);
496 }
497 else
498 {
499 h->receiving = GNUNET_NO;
500 }
501 finish (h, GNUNET_OK);
502 return; 511 return;
503 case GNUNET_MESSAGE_TYPE_STATISTICS_VALUE:
504 if (GNUNET_OK == process_message (h, msg))
505 {
506 /* finally, look for more! */
507#if DEBUG_STATISTICS
508 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
509 "Processing VALUE done, now reading more\n");
510#endif
511 GNUNET_CLIENT_receive (h->client,
512 &receive_stats,
513 h,
514 GNUNET_TIME_absolute_get_remaining
515 (h->current->timeout));
516 h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
517 return;
518 }
519 GNUNET_break (0);
520 break;
521 case GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE:
522 if (GNUNET_OK ==
523 process_watch_value (h,
524 msg))
525 {
526 h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
527 GNUNET_assert (h->watches_size > 0);
528 GNUNET_CLIENT_receive (h->client,
529 &receive_stats,
530 h,
531 GNUNET_TIME_UNIT_FOREVER_REL);
532 return;
533 }
534 GNUNET_break (0);
535 break;
536 default:
537 GNUNET_break (0);
538 break;
539 } 512 }
540 if (NULL != h->client) 513 GNUNET_break (0);
514 break;
515 case GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE:
516 if (GNUNET_OK == process_watch_value (h, msg))
541 { 517 {
542 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); 518 h->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
543 h->client = NULL; 519 GNUNET_assert (h->watches_size > 0);
520 GNUNET_CLIENT_receive (h->client,
521 &receive_stats, h, GNUNET_TIME_UNIT_FOREVER_REL);
522 return;
544 } 523 }
524 GNUNET_break (0);
525 break;
526 default:
527 GNUNET_break (0);
528 break;
529 }
530 if (NULL != h->client)
531 {
532 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO);
533 h->client = NULL;
534 }
545 finish (h, GNUNET_SYSERR); 535 finish (h, GNUNET_SYSERR);
546} 536}
547 537
@@ -559,15 +549,15 @@ transmit_get (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
559 uint16_t msize; 549 uint16_t msize;
560 550
561 if (buf == NULL) 551 if (buf == NULL)
562 { 552 {
563 /* timeout / error */ 553 /* timeout / error */
564#if DEBUG_STATISTICS 554#if DEBUG_STATISTICS
565 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 555 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
566 "Transmission of request for statistics failed!\n"); 556 "Transmission of request for statistics failed!\n");
567#endif 557#endif
568 finish (handle, GNUNET_SYSERR); 558 finish (handle, GNUNET_SYSERR);
569 return 0; 559 return 0;
570 } 560 }
571 slen1 = strlen (handle->current->subsystem) + 1; 561 slen1 = strlen (handle->current->subsystem) + 1;
572 slen2 = strlen (handle->current->name) + 1; 562 slen2 = strlen (handle->current->name) + 1;
573 msize = slen1 + slen2 + sizeof (struct GNUNET_MessageHeader); 563 msize = slen1 + slen2 + sizeof (struct GNUNET_MessageHeader);
@@ -581,19 +571,19 @@ transmit_get (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
581 2, 571 2,
582 handle->current->subsystem, 572 handle->current->subsystem,
583 handle->current->name)); 573 handle->current->name));
584 if (! handle->receiving) 574 if (!handle->receiving)
585 { 575 {
586#if DEBUG_STATISTICS 576#if DEBUG_STATISTICS
587 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 577 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
588 "Transmission of GET done, now reading response\n"); 578 "Transmission of GET done, now reading response\n");
589#endif 579#endif
590 handle->receiving = GNUNET_YES; 580 handle->receiving = GNUNET_YES;
591 GNUNET_CLIENT_receive (handle->client, 581 GNUNET_CLIENT_receive (handle->client,
592 &receive_stats, 582 &receive_stats,
593 handle, 583 handle,
594 GNUNET_TIME_absolute_get_remaining (handle-> 584 GNUNET_TIME_absolute_get_remaining (handle->
595 current->timeout)); 585 current->timeout));
596 } 586 }
597 return msize; 587 return msize;
598} 588}
599 589
@@ -611,19 +601,18 @@ transmit_watch (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
611 uint16_t msize; 601 uint16_t msize;
612 602
613 if (buf == NULL) 603 if (buf == NULL)
614 { 604 {
615 /* timeout / error */ 605 /* timeout / error */
616#if DEBUG_STATISTICS 606#if DEBUG_STATISTICS
617 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 607 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
618 "Transmission of request for statistics failed!\n"); 608 "Transmission of request for statistics failed!\n");
619#endif 609#endif
620 finish (handle, GNUNET_SYSERR); 610 finish (handle, GNUNET_SYSERR);
621 return 0; 611 return 0;
622 } 612 }
623#if DEBUG_STATISTICS 613#if DEBUG_STATISTICS
624 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 614 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
625 "Transmitting watch request for `%s'\n", 615 "Transmitting watch request for `%s'\n", handle->current->name);
626 handle->current->name);
627#endif 616#endif
628 slen1 = strlen (handle->current->subsystem) + 1; 617 slen1 = strlen (handle->current->subsystem) + 1;
629 slen2 = strlen (handle->current->name) + 1; 618 slen2 = strlen (handle->current->name) + 1;
@@ -639,13 +628,12 @@ transmit_watch (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
639 handle->current->subsystem, 628 handle->current->subsystem,
640 handle->current->name)); 629 handle->current->name));
641 if (GNUNET_YES != handle->receiving) 630 if (GNUNET_YES != handle->receiving)
642 { 631 {
643 handle->receiving = GNUNET_YES; 632 handle->receiving = GNUNET_YES;
644 GNUNET_CLIENT_receive (handle->client, 633 GNUNET_CLIENT_receive (handle->client,
645 &receive_stats, 634 &receive_stats,
646 handle, 635 handle, GNUNET_TIME_UNIT_FOREVER_REL);
647 GNUNET_TIME_UNIT_FOREVER_REL); 636 }
648 }
649 finish (handle, GNUNET_OK); 637 finish (handle, GNUNET_OK);
650 return msize; 638 return msize;
651} 639}
@@ -663,20 +651,20 @@ transmit_set (struct GNUNET_STATISTICS_Handle *handle, size_t size, void *buf)
663 size_t nsize; 651 size_t nsize;
664 652
665 if (NULL == buf) 653 if (NULL == buf)
666 { 654 {
667 finish (handle, GNUNET_SYSERR); 655 finish (handle, GNUNET_SYSERR);
668 return 0; 656 return 0;
669 } 657 }
670 658
671 slen = strlen (handle->current->subsystem) + 1; 659 slen = strlen (handle->current->subsystem) + 1;
672 nlen = strlen (handle->current->name) + 1; 660 nlen = strlen (handle->current->name) + 1;
673 nsize = sizeof (struct GNUNET_STATISTICS_SetMessage) + slen + nlen; 661 nsize = sizeof (struct GNUNET_STATISTICS_SetMessage) + slen + nlen;
674 if (size < nsize) 662 if (size < nsize)
675 { 663 {
676 GNUNET_break (0); 664 GNUNET_break (0);
677 finish (handle, GNUNET_SYSERR); 665 finish (handle, GNUNET_SYSERR);
678 return 0; 666 return 0;
679 } 667 }
680 r = buf; 668 r = buf;
681 r->header.size = htons (nsize); 669 r->header.size = htons (nsize);
682 r->header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_SET); 670 r->header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_SET);
@@ -705,22 +693,22 @@ transmit_action (void *cls, size_t size, void *buf)
705 693
706 handle->th = NULL; 694 handle->th = NULL;
707 switch (handle->current->type) 695 switch (handle->current->type)
708 { 696 {
709 case ACTION_GET: 697 case ACTION_GET:
710 ret = transmit_get (handle, size, buf); 698 ret = transmit_get (handle, size, buf);
711 break; 699 break;
712 case ACTION_SET: 700 case ACTION_SET:
713 case ACTION_UPDATE: 701 case ACTION_UPDATE:
714 ret = transmit_set (handle, size, buf); 702 ret = transmit_set (handle, size, buf);
715 break; 703 break;
716 case ACTION_WATCH: 704 case ACTION_WATCH:
717 ret = transmit_watch (handle, size, buf); 705 ret = transmit_watch (handle, size, buf);
718 break; 706 break;
719 default: 707 default:
720 ret = 0; 708 ret = 0;
721 GNUNET_break (0); 709 GNUNET_break (0);
722 break; 710 break;
723 } 711 }
724 return ret; 712 return ret;
725} 713}
726 714
@@ -745,11 +733,11 @@ GNUNET_STATISTICS_create (const char *subsystem,
745 ret->subsystem = GNUNET_strdup (subsystem); 733 ret->subsystem = GNUNET_strdup (subsystem);
746 ret->backoff = GNUNET_TIME_UNIT_MILLISECONDS; 734 ret->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
747 if (GNUNET_YES != try_connect (ret)) 735 if (GNUNET_YES != try_connect (ret))
748 { 736 {
749 GNUNET_free (ret->subsystem); 737 GNUNET_free (ret->subsystem);
750 GNUNET_free (ret); 738 GNUNET_free (ret);
751 return NULL; 739 return NULL;
752 } 740 }
753 return ret; 741 return ret;
754} 742}
755 743
@@ -763,8 +751,7 @@ GNUNET_STATISTICS_create (const char *subsystem,
763 * be completed 751 * be completed
764 */ 752 */
765void 753void
766GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h, 754GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h, int sync_first)
767 int sync_first)
768{ 755{
769 struct GNUNET_STATISTICS_GetHandle *pos; 756 struct GNUNET_STATISTICS_GetHandle *pos;
770 struct GNUNET_STATISTICS_GetHandle *next; 757 struct GNUNET_STATISTICS_GetHandle *next;
@@ -772,101 +759,97 @@ GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h,
772 struct GNUNET_TIME_Relative timeout; 759 struct GNUNET_TIME_Relative timeout;
773 int i; 760 int i;
774 761
775 if (h == NULL) 762 if (h == NULL)
776 return; 763 return;
777 if (GNUNET_SCHEDULER_NO_TASK != h->backoff_task) 764 if (GNUNET_SCHEDULER_NO_TASK != h->backoff_task)
778 GNUNET_SCHEDULER_cancel (h->backoff_task); 765 GNUNET_SCHEDULER_cancel (h->backoff_task);
779 if (sync_first) 766 if (sync_first)
767 {
768 if (h->current != NULL)
780 { 769 {
781 if (h->current != NULL) 770 if (h->current->type == ACTION_GET)
782 { 771 {
783 if (h->current->type == ACTION_GET) 772 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
784 { 773 h->th = NULL;
785 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); 774 free_action_item (h->current);
786 h->th = NULL; 775 h->current = NULL;
787 free_action_item (h->current); 776 }
788 h->current = NULL;
789 }
790 }
791 pos = h->action_head;
792 prev = NULL;
793 while (pos != NULL)
794 {
795 next = pos->next;
796 if (pos->type == ACTION_GET)
797 {
798 if (prev == NULL)
799 h->action_head = next;
800 else
801 prev->next = next;
802 free_action_item (pos);
803 }
804 else
805 {
806 prev = pos;
807 }
808 pos = next;
809 }
810 h->action_tail = prev;
811 if (h->current == NULL)
812 {
813 h->current = h->action_head;
814 if (h->action_head != NULL)
815 {
816 h->action_head = h->action_head->next;
817 if (h->action_head == NULL)
818 h->action_tail = NULL;
819 }
820 }
821 h->do_destroy = GNUNET_YES;
822 if ( (h->current != NULL) &&
823 (h->th == NULL) )
824 {
825 timeout = GNUNET_TIME_absolute_get_remaining (h->current->timeout);
826 h->th = GNUNET_CLIENT_notify_transmit_ready (h->client,
827 h->current->msize,
828 timeout,
829 GNUNET_YES,
830 &transmit_action, h);
831 GNUNET_assert (NULL != h->th);
832 }
833 if (h->th != NULL)
834 return;
835 }
836 if (NULL != h->th)
837 {
838 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
839 h->th = NULL;
840 } 777 }
841 if (h->current != NULL) 778 pos = h->action_head;
842 free_action_item (h->current); 779 prev = NULL;
843 while (NULL != (pos = h->action_head)) 780 while (pos != NULL)
844 { 781 {
845 h->action_head = pos->next; 782 next = pos->next;
846 free_action_item (pos); 783 if (pos->type == ACTION_GET)
784 {
785 if (prev == NULL)
786 h->action_head = next;
787 else
788 prev->next = next;
789 free_action_item (pos);
790 }
791 else
792 {
793 prev = pos;
794 }
795 pos = next;
847 } 796 }
848 if (h->client != NULL) 797 h->action_tail = prev;
798 if (h->current == NULL)
849 { 799 {
850 GNUNET_CLIENT_disconnect (h->client, GNUNET_YES); 800 h->current = h->action_head;
851 h->client = NULL; 801 if (h->action_head != NULL)
802 {
803 h->action_head = h->action_head->next;
804 if (h->action_head == NULL)
805 h->action_tail = NULL;
806 }
852 } 807 }
853 for (i=0;i<h->watches_size;i++) 808 h->do_destroy = GNUNET_YES;
809 if ((h->current != NULL) && (h->th == NULL))
854 { 810 {
855 GNUNET_free (h->watches[i]->subsystem); 811 timeout = GNUNET_TIME_absolute_get_remaining (h->current->timeout);
856 GNUNET_free (h->watches[i]->name); 812 h->th = GNUNET_CLIENT_notify_transmit_ready (h->client,
857 GNUNET_free (h->watches[i]); 813 h->current->msize,
814 timeout,
815 GNUNET_YES,
816 &transmit_action, h);
817 GNUNET_assert (NULL != h->th);
858 } 818 }
859 GNUNET_array_grow (h->watches, 819 if (h->th != NULL)
860 h->watches_size, 820 return;
861 0); 821 }
822 if (NULL != h->th)
823 {
824 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
825 h->th = NULL;
826 }
827 if (h->current != NULL)
828 free_action_item (h->current);
829 while (NULL != (pos = h->action_head))
830 {
831 h->action_head = pos->next;
832 free_action_item (pos);
833 }
834 if (h->client != NULL)
835 {
836 GNUNET_CLIENT_disconnect (h->client, GNUNET_YES);
837 h->client = NULL;
838 }
839 for (i = 0; i < h->watches_size; i++)
840 {
841 GNUNET_free (h->watches[i]->subsystem);
842 GNUNET_free (h->watches[i]->name);
843 GNUNET_free (h->watches[i]);
844 }
845 GNUNET_array_grow (h->watches, h->watches_size, 0);
862 GNUNET_free (h->subsystem); 846 GNUNET_free (h->subsystem);
863 GNUNET_free (h); 847 GNUNET_free (h);
864} 848}
865 849
866 850
867static void 851static void
868finish_task (void *cls, 852finish_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
869 const struct GNUNET_SCHEDULER_TaskContext *tc)
870{ 853{
871 struct GNUNET_STATISTICS_Handle *h = cls; 854 struct GNUNET_STATISTICS_Handle *h = cls;
872 855
@@ -886,44 +869,41 @@ schedule_action (struct GNUNET_STATISTICS_Handle *h)
886 if (h->current != NULL) 869 if (h->current != NULL)
887 return; /* action already pending */ 870 return; /* action already pending */
888 if (GNUNET_YES != try_connect (h)) 871 if (GNUNET_YES != try_connect (h))
889 { 872 {
890 h->backoff_task = GNUNET_SCHEDULER_add_delayed (h->backoff, 873 h->backoff_task = GNUNET_SCHEDULER_add_delayed (h->backoff,
891 &finish_task, 874 &finish_task, h);
892 h); 875 h->backoff = GNUNET_TIME_relative_multiply (h->backoff, 2);
893 h->backoff = GNUNET_TIME_relative_multiply (h->backoff, 2); 876 h->backoff = GNUNET_TIME_relative_min (h->backoff,
894 h->backoff = GNUNET_TIME_relative_min (h->backoff, 877 GNUNET_CONSTANTS_SERVICE_TIMEOUT);
895 GNUNET_CONSTANTS_SERVICE_TIMEOUT); 878 return;
896 return; 879 }
897 }
898 880
899 /* schedule next action */ 881 /* schedule next action */
900 h->current = h->action_head; 882 h->current = h->action_head;
901 if (NULL == h->current) 883 if (NULL == h->current)
884 {
885 if (h->do_destroy)
902 { 886 {
903 if (h->do_destroy) 887 h->do_destroy = GNUNET_NO;
904 { 888 GNUNET_STATISTICS_destroy (h, GNUNET_YES);
905 h->do_destroy = GNUNET_NO;
906 GNUNET_STATISTICS_destroy (h, GNUNET_YES);
907 }
908 return;
909 } 889 }
910 GNUNET_CONTAINER_DLL_remove (h->action_head, 890 return;
911 h->action_tail, 891 }
912 h->current); 892 GNUNET_CONTAINER_DLL_remove (h->action_head, h->action_tail, h->current);
913 timeout = GNUNET_TIME_absolute_get_remaining (h->current->timeout); 893 timeout = GNUNET_TIME_absolute_get_remaining (h->current->timeout);
914 if (NULL == 894 if (NULL ==
915 (h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, 895 (h->th = GNUNET_CLIENT_notify_transmit_ready (h->client,
916 h->current->msize, 896 h->current->msize,
917 timeout, 897 timeout,
918 GNUNET_YES, 898 GNUNET_YES,
919 &transmit_action, h))) 899 &transmit_action, h)))
920 { 900 {
921#if DEBUG_STATISTICS 901#if DEBUG_STATISTICS
922 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 902 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
923 "Failed to transmit request to statistics service.\n"); 903 "Failed to transmit request to statistics service.\n");
924#endif 904#endif
925 finish (h, GNUNET_SYSERR); 905 finish (h, GNUNET_SYSERR);
926 } 906 }
927} 907}
928 908
929 909
@@ -956,15 +936,15 @@ GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle,
956 GNUNET_assert (proc != NULL); 936 GNUNET_assert (proc != NULL);
957 GNUNET_assert (GNUNET_NO == handle->do_destroy); 937 GNUNET_assert (GNUNET_NO == handle->do_destroy);
958 if (GNUNET_YES != try_connect (handle)) 938 if (GNUNET_YES != try_connect (handle))
959 { 939 {
960#if DEBUG_STATISTICS 940#if DEBUG_STATISTICS
961 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 941 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
962 "Failed to connect to statistics service, can not get value `%s:%s'.\n", 942 "Failed to connect to statistics service, can not get value `%s:%s'.\n",
963 strlen (subsystem) ? subsystem : "*", 943 strlen (subsystem) ? subsystem : "*",
964 strlen (name) ? name : "*"); 944 strlen (name) ? name : "*");
965#endif 945#endif
966 return NULL; 946 return NULL;
967 } 947 }
968 if (subsystem == NULL) 948 if (subsystem == NULL)
969 subsystem = ""; 949 subsystem = "";
970 if (name == NULL) 950 if (name == NULL)
@@ -998,18 +978,16 @@ void
998GNUNET_STATISTICS_get_cancel (struct GNUNET_STATISTICS_GetHandle *gh) 978GNUNET_STATISTICS_get_cancel (struct GNUNET_STATISTICS_GetHandle *gh)
999{ 979{
1000 if (gh->sh->current == gh) 980 if (gh->sh->current == gh)
1001 { 981 {
1002 gh->aborted = GNUNET_YES; 982 gh->aborted = GNUNET_YES;
1003 } 983 }
1004 else 984 else
1005 { 985 {
1006 GNUNET_CONTAINER_DLL_remove (gh->sh->action_head, 986 GNUNET_CONTAINER_DLL_remove (gh->sh->action_head, gh->sh->action_tail, gh);
1007 gh->sh->action_tail, 987 GNUNET_free (gh->name);
1008 gh); 988 GNUNET_free (gh->subsystem);
1009 GNUNET_free (gh->name); 989 GNUNET_free (gh);
1010 GNUNET_free (gh->subsystem); 990 }
1011 GNUNET_free (gh);
1012 }
1013} 991}
1014 992
1015 993
@@ -1027,23 +1005,20 @@ GNUNET_STATISTICS_get_cancel (struct GNUNET_STATISTICS_GetHandle *gh)
1027 */ 1005 */
1028int 1006int
1029GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle, 1007GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle,
1030 const char *subsystem, 1008 const char *subsystem,
1031 const char *name, 1009 const char *name,
1032 GNUNET_STATISTICS_Iterator proc, 1010 GNUNET_STATISTICS_Iterator proc, void *proc_cls)
1033 void *proc_cls)
1034{ 1011{
1035 struct GNUNET_STATISTICS_WatchEntry *w; 1012 struct GNUNET_STATISTICS_WatchEntry *w;
1036 1013
1037 if (handle == NULL) 1014 if (handle == NULL)
1038 return GNUNET_SYSERR; 1015 return GNUNET_SYSERR;
1039 w = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_WatchEntry)); 1016 w = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_WatchEntry));
1040 w->subsystem = GNUNET_strdup (subsystem); 1017 w->subsystem = GNUNET_strdup (subsystem);
1041 w->name = GNUNET_strdup (name); 1018 w->name = GNUNET_strdup (name);
1042 w->proc = proc; 1019 w->proc = proc;
1043 w->proc_cls = proc_cls; 1020 w->proc_cls = proc_cls;
1044 GNUNET_array_append (handle->watches, 1021 GNUNET_array_append (handle->watches, handle->watches_size, w);
1045 handle->watches_size,
1046 w);
1047 schedule_watch_request (handle, w); 1022 schedule_watch_request (handle, w);
1048 return GNUNET_OK; 1023 return GNUNET_OK;
1049} 1024}
@@ -1052,15 +1027,14 @@ GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle,
1052static void 1027static void
1053add_setter_action (struct GNUNET_STATISTICS_Handle *h, 1028add_setter_action (struct GNUNET_STATISTICS_Handle *h,
1054 const char *name, 1029 const char *name,
1055 int make_persistent, 1030 int make_persistent, uint64_t value, enum ActionType type)
1056 uint64_t value, enum ActionType type)
1057{ 1031{
1058 struct GNUNET_STATISTICS_GetHandle *ai; 1032 struct GNUNET_STATISTICS_GetHandle *ai;
1059 size_t slen; 1033 size_t slen;
1060 size_t nlen; 1034 size_t nlen;
1061 size_t nsize; 1035 size_t nsize;
1062 int64_t delta; 1036 int64_t delta;
1063 1037
1064 GNUNET_assert (h != NULL); 1038 GNUNET_assert (h != NULL);
1065 GNUNET_assert (name != NULL); 1039 GNUNET_assert (name != NULL);
1066 if (GNUNET_YES != try_connect (h)) 1040 if (GNUNET_YES != try_connect (h))
@@ -1069,59 +1043,58 @@ add_setter_action (struct GNUNET_STATISTICS_Handle *h,
1069 nlen = strlen (name) + 1; 1043 nlen = strlen (name) + 1;
1070 nsize = sizeof (struct GNUNET_STATISTICS_SetMessage) + slen + nlen; 1044 nsize = sizeof (struct GNUNET_STATISTICS_SetMessage) + slen + nlen;
1071 if (nsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1045 if (nsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1072 { 1046 {
1073 GNUNET_break (0); 1047 GNUNET_break (0);
1074 return; 1048 return;
1075 } 1049 }
1076 ai = h->action_head; 1050 ai = h->action_head;
1077 while (ai != NULL) 1051 while (ai != NULL)
1052 {
1053 if ((0 == strcmp (ai->subsystem, h->subsystem)) &&
1054 (0 == strcmp (ai->name, name)) &&
1055 ((ai->type == ACTION_UPDATE) || (ai->type == ACTION_SET)))
1078 { 1056 {
1079 if ( (0 == strcmp (ai->subsystem, h->subsystem)) && 1057 if (ai->type == ACTION_SET)
1080 (0 == strcmp (ai->name, name)) && 1058 {
1081 ( (ai->type == ACTION_UPDATE) || 1059 if (type == ACTION_UPDATE)
1082 (ai->type == ACTION_SET) ) ) 1060 {
1083 { 1061 delta = (int64_t) value;
1084 if (ai->type == ACTION_SET) 1062 if (delta > 0)
1085 { 1063 {
1086 if (type == ACTION_UPDATE) 1064 ai->value += delta;
1087 { 1065 }
1088 delta = (int64_t) value; 1066 else
1089 if (delta > 0) 1067 {
1090 { 1068 if (ai->value < -delta)
1091 ai->value += delta; 1069 ai->value = 0;
1092 } 1070 else
1093 else 1071 ai->value += delta;
1094 { 1072 }
1095 if (ai->value < -delta) 1073 }
1096 ai->value = 0; 1074 else
1097 else 1075 {
1098 ai->value += delta; 1076 ai->value = value;
1099 } 1077 }
1100 } 1078 }
1101 else 1079 else
1102 { 1080 {
1103 ai->value = value; 1081 if (type == ACTION_UPDATE)
1104 } 1082 {
1105 } 1083 delta = (int64_t) value;
1106 else 1084 ai->value += delta;
1107 { 1085 }
1108 if (type == ACTION_UPDATE) 1086 else
1109 { 1087 {
1110 delta = (int64_t) value; 1088 ai->value = value;
1111 ai->value += delta; 1089 ai->type = type;
1112 } 1090 }
1113 else 1091 }
1114 { 1092 ai->timeout = GNUNET_TIME_relative_to_absolute (SET_TRANSMIT_TIMEOUT);
1115 ai->value = value; 1093 ai->make_persistent = make_persistent;
1116 ai->type = type; 1094 return;
1117 }
1118 }
1119 ai->timeout = GNUNET_TIME_relative_to_absolute (SET_TRANSMIT_TIMEOUT);
1120 ai->make_persistent = make_persistent;
1121 return;
1122 }
1123 ai = ai->next;
1124 } 1095 }
1096 ai = ai->next;
1097 }
1125 ai = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_GetHandle)); 1098 ai = GNUNET_malloc (sizeof (struct GNUNET_STATISTICS_GetHandle));
1126 ai->sh = h; 1099 ai->sh = h;
1127 ai->subsystem = GNUNET_strdup (h->subsystem); 1100 ai->subsystem = GNUNET_strdup (h->subsystem);
@@ -1146,8 +1119,7 @@ add_setter_action (struct GNUNET_STATISTICS_Handle *h,
1146 */ 1119 */
1147void 1120void
1148GNUNET_STATISTICS_set (struct GNUNET_STATISTICS_Handle *handle, 1121GNUNET_STATISTICS_set (struct GNUNET_STATISTICS_Handle *handle,
1149 const char *name, 1122 const char *name, uint64_t value, int make_persistent)
1150 uint64_t value, int make_persistent)
1151{ 1123{
1152 if (handle == NULL) 1124 if (handle == NULL)
1153 return; 1125 return;
@@ -1167,8 +1139,7 @@ GNUNET_STATISTICS_set (struct GNUNET_STATISTICS_Handle *handle,
1167 */ 1139 */
1168void 1140void
1169GNUNET_STATISTICS_update (struct GNUNET_STATISTICS_Handle *handle, 1141GNUNET_STATISTICS_update (struct GNUNET_STATISTICS_Handle *handle,
1170 const char *name, 1142 const char *name, int64_t delta, int make_persistent)
1171 int64_t delta, int make_persistent)
1172{ 1143{
1173 if (handle == NULL) 1144 if (handle == NULL)
1174 return; 1145 return;