aboutsummaryrefslogtreecommitdiff
path: root/src/statistics/gnunet-service-statistics.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-08-15 21:46:35 +0000
committerChristian Grothoff <christian@grothoff.org>2011-08-15 21:46:35 +0000
commit502af2167f7c218366666ca4944bd7cc54b5b19a (patch)
treea91fec5cc9769d260640bd91c6633cb9cf395524 /src/statistics/gnunet-service-statistics.c
parent03af5a603b7cc53432249d5854cd412aa90dde0d (diff)
downloadgnunet-502af2167f7c218366666ca4944bd7cc54b5b19a.tar.gz
gnunet-502af2167f7c218366666ca4944bd7cc54b5b19a.zip
indentation
Diffstat (limited to 'src/statistics/gnunet-service-statistics.c')
-rw-r--r--src/statistics/gnunet-service-statistics.c468
1 files changed, 216 insertions, 252 deletions
diff --git a/src/statistics/gnunet-service-statistics.c b/src/statistics/gnunet-service-statistics.c
index c506dee7b..5e0be1183 100644
--- a/src/statistics/gnunet-service-statistics.c
+++ b/src/statistics/gnunet-service-statistics.c
@@ -50,7 +50,7 @@ struct WatchEntry
50 struct GNUNET_SERVER_Client *client; 50 struct GNUNET_SERVER_Client *client;
51 51
52 uint64_t last_value; 52 uint64_t last_value;
53 53
54 uint32_t wid; 54 uint32_t wid;
55 55
56}; 56};
@@ -67,7 +67,7 @@ struct ClientEntry
67 struct ClientEntry *prev; 67 struct ClientEntry *prev;
68 68
69 struct GNUNET_SERVER_Client *client; 69 struct GNUNET_SERVER_Client *client;
70 70
71 uint32_t max_wid; 71 uint32_t max_wid;
72 72
73}; 73};
@@ -156,9 +156,7 @@ static uint32_t uidgen;
156 156
157 157
158static void 158static void
159inject_message (void *cls, 159inject_message (void *cls, void *client, const struct GNUNET_MessageHeader *msg)
160 void *client,
161 const struct GNUNET_MessageHeader *msg)
162{ 160{
163 struct GNUNET_SERVER_Handle *server = cls; 161 struct GNUNET_SERVER_Handle *server = cls;
164 162
@@ -188,37 +186,33 @@ load (struct GNUNET_SERVER_Handle *server)
188 if (fn == NULL) 186 if (fn == NULL)
189 return; 187 return;
190 if ((0 != stat (fn, &sb)) || (sb.st_size == 0)) 188 if ((0 != stat (fn, &sb)) || (sb.st_size == 0))
191 { 189 {
192 GNUNET_free (fn); 190 GNUNET_free (fn);
193 return; 191 return;
194 } 192 }
195 fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_READ, 193 fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE);
196 GNUNET_DISK_PERM_NONE);
197 if (!fh) 194 if (!fh)
198 { 195 {
199 GNUNET_free (fn); 196 GNUNET_free (fn);
200 return; 197 return;
201 } 198 }
202 buf = GNUNET_DISK_file_map (fh, &mh, GNUNET_DISK_MAP_TYPE_READ, sb.st_size); 199 buf = GNUNET_DISK_file_map (fh, &mh, GNUNET_DISK_MAP_TYPE_READ, sb.st_size);
203 if (NULL == buf) 200 if (NULL == buf)
204 { 201 {
205 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "mmap", fn); 202 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "mmap", fn);
206 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh)); 203 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh));
207 GNUNET_free (fn); 204 GNUNET_free (fn);
208 return; 205 return;
209 } 206 }
210 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 207 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
211 _("Loading %llu bytes of statistics from `%s'\n"), 208 _("Loading %llu bytes of statistics from `%s'\n"),
212 (unsigned long long) sb.st_size, fn); 209 (unsigned long long) sb.st_size, fn);
213 mst = GNUNET_SERVER_mst_create (&inject_message, 210 mst = GNUNET_SERVER_mst_create (&inject_message, server);
214 server);
215 GNUNET_break (GNUNET_OK == 211 GNUNET_break (GNUNET_OK ==
216 GNUNET_SERVER_mst_receive (mst, 212 GNUNET_SERVER_mst_receive (mst,
217 NULL, 213 NULL,
218 buf, 214 buf,
219 sb.st_size, 215 sb.st_size, GNUNET_YES, GNUNET_NO));
220 GNUNET_YES,
221 GNUNET_NO));
222 GNUNET_SERVER_mst_destroy (mst); 216 GNUNET_SERVER_mst_destroy (mst);
223 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_unmap (mh)); 217 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_unmap (mh));
224 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh)); 218 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh));
@@ -229,7 +223,7 @@ load (struct GNUNET_SERVER_Handle *server)
229 * Write persistent statistics to disk. 223 * Write persistent statistics to disk.
230 */ 224 */
231static void 225static void
232save () 226save ()
233{ 227{
234 struct StatsEntry *pos; 228 struct StatsEntry *pos;
235 char *fn; 229 char *fn;
@@ -242,36 +236,37 @@ save ()
242 "statistics", "statistics.data", NULL); 236 "statistics", "statistics.data", NULL);
243 if (fn != NULL) 237 if (fn != NULL)
244 fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_WRITE 238 fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_WRITE
245 | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE, 239 | GNUNET_DISK_OPEN_CREATE |
246 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); 240 GNUNET_DISK_OPEN_TRUNCATE,
241 GNUNET_DISK_PERM_USER_READ |
242 GNUNET_DISK_PERM_USER_WRITE);
247 total = 0; 243 total = 0;
248 while (NULL != (pos = start)) 244 while (NULL != (pos = start))
245 {
246 start = pos->next;
247 if ((pos->persistent) && (NULL != fh))
249 { 248 {
250 start = pos->next; 249 size = htons (pos->msg->header.size);
251 if ((pos->persistent) && (NULL != fh)) 250 if (size != GNUNET_DISK_file_write (fh, pos->msg, size))
252 { 251 {
253 size = htons (pos->msg->header.size); 252 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn);
254 if (size != GNUNET_DISK_file_write (fh, pos->msg, size)) 253 GNUNET_DISK_file_close (fh);
255 { 254 fh = NULL;
256 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, 255 }
257 "write", fn);
258 GNUNET_DISK_file_close (fh);
259 fh = NULL;
260 }
261 else
262 total += size;
263 }
264 GNUNET_free (pos);
265 }
266 if (NULL != fh)
267 {
268 GNUNET_DISK_file_close (fh);
269 if (total == 0)
270 GNUNET_break (0 == UNLINK (fn));
271 else 256 else
272 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 257 total += size;
273 _("Wrote %llu bytes of statistics to `%s'\n"), total, fn);
274 } 258 }
259 GNUNET_free (pos);
260 }
261 if (NULL != fh)
262 {
263 GNUNET_DISK_file_close (fh);
264 if (total == 0)
265 GNUNET_break (0 == UNLINK (fn));
266 else
267 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
268 _("Wrote %llu bytes of statistics to `%s'\n"), total, fn);
269 }
275 GNUNET_free_non_null (fn); 270 GNUNET_free_non_null (fn);
276} 271}
277 272
@@ -280,15 +275,14 @@ save ()
280 * Transmit the given stats value. 275 * Transmit the given stats value.
281 */ 276 */
282static void 277static void
283transmit (struct GNUNET_SERVER_Client *client, 278transmit (struct GNUNET_SERVER_Client *client, const struct StatsEntry *e)
284 const struct StatsEntry *e)
285{ 279{
286 struct GNUNET_STATISTICS_ReplyMessage *m; 280 struct GNUNET_STATISTICS_ReplyMessage *m;
287 size_t size; 281 size_t size;
288 282
289 size = 283 size =
290 sizeof (struct GNUNET_STATISTICS_ReplyMessage) + strlen (e->service) + 1 + 284 sizeof (struct GNUNET_STATISTICS_ReplyMessage) + strlen (e->service) + 1 +
291 strlen (e->name) + 1; 285 strlen (e->name) + 1;
292 GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE); 286 GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
293 m = GNUNET_malloc (size); 287 m = GNUNET_malloc (size);
294 m->header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_VALUE); 288 m->header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_VALUE);
@@ -304,10 +298,10 @@ transmit (struct GNUNET_SERVER_Client *client,
304#if DEBUG_STATISTICS 298#if DEBUG_STATISTICS
305 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 299 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
306 "Transmitting value for `%s:%s' (%d): %llu\n", 300 "Transmitting value for `%s:%s' (%d): %llu\n",
307 e->service, e->name, 301 e->service, e->name, e->persistent, e->value);
308 e->persistent, e->value);
309#endif 302#endif
310 GNUNET_SERVER_notification_context_unicast (nc, client, &m->header, GNUNET_NO); 303 GNUNET_SERVER_notification_context_unicast (nc, client, &m->header,
304 GNUNET_NO);
311 GNUNET_free (m); 305 GNUNET_free (m);
312} 306}
313 307
@@ -320,7 +314,7 @@ matches (const struct StatsEntry *e, const char *service, const char *name)
320{ 314{
321 return ((0 == strlen (service)) || 315 return ((0 == strlen (service)) ||
322 (0 == strcmp (service, e->service))) 316 (0 == strcmp (service, e->service)))
323 && ((0 == strlen (name)) || (0 == strcmp (name, e->name))); 317 && ((0 == strlen (name)) || (0 == strcmp (name, e->name)));
324} 318}
325 319
326 320
@@ -332,19 +326,16 @@ make_client_entry (struct GNUNET_SERVER_Client *client)
332 GNUNET_assert (client != NULL); 326 GNUNET_assert (client != NULL);
333 ce = client_head; 327 ce = client_head;
334 while (ce != NULL) 328 while (ce != NULL)
335 { 329 {
336 if (ce->client == client) 330 if (ce->client == client)
337 return ce; 331 return ce;
338 ce = ce->next; 332 ce = ce->next;
339 } 333 }
340 ce = GNUNET_malloc (sizeof (struct ClientEntry)); 334 ce = GNUNET_malloc (sizeof (struct ClientEntry));
341 ce->client = client; 335 ce->client = client;
342 GNUNET_SERVER_client_keep (client); 336 GNUNET_SERVER_client_keep (client);
343 GNUNET_CONTAINER_DLL_insert (client_head, 337 GNUNET_CONTAINER_DLL_insert (client_head, client_tail, ce);
344 client_tail, 338 GNUNET_SERVER_notification_context_add (nc, client);
345 ce);
346 GNUNET_SERVER_notification_context_add (nc,
347 client);
348 return ce; 339 return ce;
349} 340}
350 341
@@ -374,11 +365,11 @@ handle_get (void *cls,
374 size = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader); 365 size = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader);
375 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1], 366 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
376 size, 2, &service, &name)) 367 size, 2, &service, &name))
377 { 368 {
378 GNUNET_break (0); 369 GNUNET_break (0);
379 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 370 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
380 return; 371 return;
381 } 372 }
382#if DEBUG_STATISTICS 373#if DEBUG_STATISTICS
383 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 374 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
384 "Received request for statistics on `%s:%s'\n", 375 "Received request for statistics on `%s:%s'\n",
@@ -386,19 +377,15 @@ handle_get (void *cls,
386#endif 377#endif
387 pos = start; 378 pos = start;
388 while (pos != NULL) 379 while (pos != NULL)
389 { 380 {
390 if (matches (pos, service, name)) 381 if (matches (pos, service, name))
391 transmit (client, pos); 382 transmit (client, pos);
392 pos = pos->next; 383 pos = pos->next;
393 } 384 }
394 end.size = htons (sizeof (struct GNUNET_MessageHeader)); 385 end.size = htons (sizeof (struct GNUNET_MessageHeader));
395 end.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_END); 386 end.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_END);
396 GNUNET_SERVER_notification_context_unicast (nc, 387 GNUNET_SERVER_notification_context_unicast (nc, client, &end, GNUNET_NO);
397 client, 388 GNUNET_SERVER_receive_done (client, GNUNET_OK);
398 &end,
399 GNUNET_NO);
400 GNUNET_SERVER_receive_done (client,
401 GNUNET_OK);
402} 389}
403 390
404 391
@@ -410,23 +397,23 @@ notify_change (struct StatsEntry *se)
410 397
411 pos = se->we_head; 398 pos = se->we_head;
412 while (pos != NULL) 399 while (pos != NULL)
400 {
401 if (pos->last_value != se->value)
413 { 402 {
414 if (pos->last_value != se->value) 403 wvm.header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE);
415 { 404 wvm.header.size =
416 wvm.header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE); 405 htons (sizeof (struct GNUNET_STATISTICS_WatchValueMessage));
417 wvm.header.size = htons (sizeof (struct GNUNET_STATISTICS_WatchValueMessage)); 406 wvm.flags = htonl (se->persistent ? GNUNET_STATISTICS_PERSIST_BIT : 0);
418 wvm.flags = htonl (se->persistent ? GNUNET_STATISTICS_PERSIST_BIT : 0); 407 wvm.wid = htonl (pos->wid);
419 wvm.wid = htonl (pos->wid); 408 wvm.reserved = htonl (0);
420 wvm.reserved = htonl (0); 409 wvm.value = GNUNET_htonll (se->value);
421 wvm.value = GNUNET_htonll (se->value); 410 GNUNET_SERVER_notification_context_unicast (nc,
422 GNUNET_SERVER_notification_context_unicast (nc, 411 pos->client,
423 pos->client, 412 &wvm.header, GNUNET_NO);
424 &wvm.header, 413 pos->last_value = se->value;
425 GNUNET_NO);
426 pos->last_value = se->value;
427 }
428 pos = pos->next;
429 } 414 }
415 pos = pos->next;
416 }
430} 417}
431 418
432/** 419/**
@@ -457,81 +444,77 @@ handle_set (void *cls,
457 make_client_entry (client); 444 make_client_entry (client);
458 msize = ntohs (message->size); 445 msize = ntohs (message->size);
459 if (msize < sizeof (struct GNUNET_STATISTICS_SetMessage)) 446 if (msize < sizeof (struct GNUNET_STATISTICS_SetMessage))
460 { 447 {
461 GNUNET_break (0); 448 GNUNET_break (0);
462 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 449 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
463 return; 450 return;
464 } 451 }
465 size = msize - sizeof (struct GNUNET_STATISTICS_SetMessage); 452 size = msize - sizeof (struct GNUNET_STATISTICS_SetMessage);
466 msg = (const struct GNUNET_STATISTICS_SetMessage *) message; 453 msg = (const struct GNUNET_STATISTICS_SetMessage *) message;
467 454
468 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &msg[1], 455 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &msg[1],
469 size, 2, &service, &name)) 456 size, 2, &service, &name))
470 { 457 {
471 GNUNET_break (0); 458 GNUNET_break (0);
472 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 459 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
473 return; 460 return;
474 } 461 }
475 flags = ntohl (msg->flags); 462 flags = ntohl (msg->flags);
476 value = GNUNET_ntohll (msg->value); 463 value = GNUNET_ntohll (msg->value);
477#if DEBUG_STATISTICS 464#if DEBUG_STATISTICS
478 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 465 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
479 "Received request to update statistic on `%s:%s' (%u) to/by %llu\n", 466 "Received request to update statistic on `%s:%s' (%u) to/by %llu\n",
480 service, name, 467 service, name, (unsigned int) flags, (unsigned long long) value);
481 (unsigned int) flags,
482 (unsigned long long) value);
483#endif 468#endif
484 pos = start; 469 pos = start;
485 prev = NULL; 470 prev = NULL;
486 while (pos != NULL) 471 while (pos != NULL)
472 {
473 if (matches (pos, service, name))
487 { 474 {
488 if (matches (pos, service, name)) 475 if ((flags & GNUNET_STATISTICS_SETFLAG_RELATIVE) == 0)
476 {
477 changed = (pos->value != value);
478 pos->value = value;
479 }
480 else
481 {
482 delta = (int64_t) value;
483 if ((delta < 0) && (pos->value < -delta))
484 {
485 changed = (pos->value != 0);
486 pos->value = 0;
487 }
488 else
489 { 489 {
490 if ((flags & GNUNET_STATISTICS_SETFLAG_RELATIVE) == 0) 490 changed = (delta != 0);
491 { 491 GNUNET_break ((delta <= 0) || (pos->value + delta > pos->value));
492 changed = (pos->value != value); 492 pos->value += delta;
493 pos->value = value; 493 }
494 } 494 }
495 else 495 pos->msg->value = GNUNET_htonll (pos->value);
496 { 496 pos->msg->flags = msg->flags;
497 delta = (int64_t) value; 497 pos->persistent = (0 != (flags & GNUNET_STATISTICS_SETFLAG_PERSISTENT));
498 if ((delta < 0) && (pos->value < -delta)) 498 if (prev != NULL)
499 { 499 {
500 changed = (pos->value != 0); 500 /* move to front for faster setting next time! */
501 pos->value = 0; 501 prev->next = pos->next;
502 } 502 pos->next = start;
503 else 503 start = pos;
504 { 504 }
505 changed = (delta != 0);
506 GNUNET_break ((delta <= 0) ||
507 (pos->value + delta > pos->value));
508 pos->value += delta;
509 }
510 }
511 pos->msg->value = GNUNET_htonll (pos->value);
512 pos->msg->flags = msg->flags;
513 pos->persistent =
514 (0 != (flags & GNUNET_STATISTICS_SETFLAG_PERSISTENT));
515 if (prev != NULL)
516 {
517 /* move to front for faster setting next time! */
518 prev->next = pos->next;
519 pos->next = start;
520 start = pos;
521 }
522#if DEBUG_STATISTICS 505#if DEBUG_STATISTICS
523 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 506 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
524 "Statistic `%s:%s' updated to value %llu.\n", 507 "Statistic `%s:%s' updated to value %llu.\n",
525 service, name, pos->value); 508 service, name, pos->value);
526#endif 509#endif
527 if (changed) 510 if (changed)
528 notify_change (pos); 511 notify_change (pos);
529 GNUNET_SERVER_receive_done (client, GNUNET_OK); 512 GNUNET_SERVER_receive_done (client, GNUNET_OK);
530 return; 513 return;
531 }
532 prev = pos;
533 pos = pos->next;
534 } 514 }
515 prev = pos;
516 pos = pos->next;
517 }
535 pos = GNUNET_malloc (sizeof (struct StatsEntry) + msize); 518 pos = GNUNET_malloc (sizeof (struct StatsEntry) + msize);
536 pos->next = start; 519 pos->next = start;
537 if (((flags & GNUNET_STATISTICS_SETFLAG_RELATIVE) == 0) || 520 if (((flags & GNUNET_STATISTICS_SETFLAG_RELATIVE) == 0) ||
@@ -563,8 +546,8 @@ handle_set (void *cls,
563 */ 546 */
564static void 547static void
565handle_watch (void *cls, 548handle_watch (void *cls,
566 struct GNUNET_SERVER_Client *client, 549 struct GNUNET_SERVER_Client *client,
567 const struct GNUNET_MessageHeader *message) 550 const struct GNUNET_MessageHeader *message)
568{ 551{
569 char *service; 552 char *service;
570 char *name; 553 char *name;
@@ -578,19 +561,19 @@ handle_watch (void *cls,
578 ce = make_client_entry (client); 561 ce = make_client_entry (client);
579 msize = ntohs (message->size); 562 msize = ntohs (message->size);
580 if (msize < sizeof (struct GNUNET_MessageHeader)) 563 if (msize < sizeof (struct GNUNET_MessageHeader))
581 { 564 {
582 GNUNET_break (0); 565 GNUNET_break (0);
583 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 566 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
584 return; 567 return;
585 } 568 }
586 size = msize - sizeof (struct GNUNET_MessageHeader); 569 size = msize - sizeof (struct GNUNET_MessageHeader);
587 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1], 570 if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
588 size, 2, &service, &name)) 571 size, 2, &service, &name))
589 { 572 {
590 GNUNET_break (0); 573 GNUNET_break (0);
591 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 574 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
592 return; 575 return;
593 } 576 }
594#if DEBUG_STATISTICS 577#if DEBUG_STATISTICS
595 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 578 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
596 "Received request to watch statistic on `%s:%s'\n", 579 "Received request to watch statistic on `%s:%s'\n",
@@ -598,40 +581,36 @@ handle_watch (void *cls,
598#endif 581#endif
599 pos = start; 582 pos = start;
600 while (pos != NULL) 583 while (pos != NULL)
601 { 584 {
602 if (matches (pos, service, name)) 585 if (matches (pos, service, name))
603 break; 586 break;
604 pos = pos->next; 587 pos = pos->next;
605 } 588 }
606 if (pos == NULL) 589 if (pos == NULL)
607 { 590 {
608 pos = GNUNET_malloc (sizeof (struct StatsEntry) + 591 pos = GNUNET_malloc (sizeof (struct StatsEntry) +
609 sizeof (struct GNUNET_STATISTICS_SetMessage) + 592 sizeof (struct GNUNET_STATISTICS_SetMessage) + size);
610 size); 593 pos->next = start;
611 pos->next = start; 594 pos->uid = uidgen++;
612 pos->uid = uidgen++; 595 pos->msg = (void *) &pos[1];
613 pos->msg = (void *) &pos[1]; 596 pos->msg->header.size =
614 pos->msg->header.size = htons (sizeof (struct GNUNET_STATISTICS_SetMessage) + 597 htons (sizeof (struct GNUNET_STATISTICS_SetMessage) + size);
615 size); 598 pos->msg->header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_SET);
616 pos->msg->header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_SET); 599 pos->service = (const char *) &pos->msg[1];
617 pos->service = (const char *) &pos->msg[1]; 600 slen = strlen (service) + 1;
618 slen = strlen (service) + 1; 601 memcpy ((void *) pos->service, service, slen);
619 memcpy ((void*) pos->service, service, slen); 602 pos->name = &pos->service[slen];
620 pos->name = &pos->service[slen]; 603 memcpy ((void *) pos->name, name, strlen (name) + 1);
621 memcpy ((void*) pos->name, name, strlen (name)+1); 604 start = pos;
622 start = pos; 605 }
623 }
624 we = GNUNET_malloc (sizeof (struct WatchEntry)); 606 we = GNUNET_malloc (sizeof (struct WatchEntry));
625 we->client = client; 607 we->client = client;
626 GNUNET_SERVER_client_keep (client); 608 GNUNET_SERVER_client_keep (client);
627 we->wid = ce->max_wid++; 609 we->wid = ce->max_wid++;
628 GNUNET_CONTAINER_DLL_insert (pos->we_head, 610 GNUNET_CONTAINER_DLL_insert (pos->we_head, pos->we_tail, we);
629 pos->we_tail,
630 we);
631 if (pos->value != 0) 611 if (pos->value != 0)
632 notify_change (pos); 612 notify_change (pos);
633 GNUNET_SERVER_receive_done (client, 613 GNUNET_SERVER_receive_done (client, GNUNET_OK);
634 GNUNET_OK);
635} 614}
636 615
637 616
@@ -642,8 +621,7 @@ handle_watch (void *cls,
642 * @param tc unused 621 * @param tc unused
643 */ 622 */
644static void 623static void
645shutdown_task (void *cls, 624shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
646 const struct GNUNET_SCHEDULER_TaskContext *tc)
647{ 625{
648 struct ClientEntry *ce; 626 struct ClientEntry *ce;
649 struct WatchEntry *we; 627 struct WatchEntry *we;
@@ -653,26 +631,22 @@ shutdown_task (void *cls,
653 GNUNET_SERVER_notification_context_destroy (nc); 631 GNUNET_SERVER_notification_context_destroy (nc);
654 nc = NULL; 632 nc = NULL;
655 while (NULL != (ce = client_head)) 633 while (NULL != (ce = client_head))
656 { 634 {
657 GNUNET_SERVER_client_drop (ce->client); 635 GNUNET_SERVER_client_drop (ce->client);
658 GNUNET_CONTAINER_DLL_remove (client_head, 636 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, ce);
659 client_tail, 637 GNUNET_free (ce);
660 ce); 638 }
661 GNUNET_free (ce);
662 }
663 while (NULL != (se = start)) 639 while (NULL != (se = start))
640 {
641 start = se->next;
642 while (NULL != (we = se->we_head))
664 { 643 {
665 start = se->next; 644 GNUNET_SERVER_client_drop (we->client);
666 while (NULL != (we = se->we_head)) 645 GNUNET_CONTAINER_DLL_remove (se->we_head, se->we_tail, we);
667 { 646 GNUNET_free (we);
668 GNUNET_SERVER_client_drop (we->client);
669 GNUNET_CONTAINER_DLL_remove (se->we_head,
670 se->we_tail,
671 we);
672 GNUNET_free (we);
673 }
674 GNUNET_free (se);
675 } 647 }
648 GNUNET_free (se);
649 }
676} 650}
677 651
678 652
@@ -683,46 +657,40 @@ shutdown_task (void *cls,
683 * @param client identification of the client 657 * @param client identification of the client
684 */ 658 */
685static void 659static void
686handle_client_disconnect (void *cls, 660handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
687 struct GNUNET_SERVER_Client
688 * client)
689{ 661{
690 struct ClientEntry *ce; 662 struct ClientEntry *ce;
691 struct WatchEntry *we; 663 struct WatchEntry *we;
692 struct WatchEntry *wen; 664 struct WatchEntry *wen;
693 struct StatsEntry *se; 665 struct StatsEntry *se;
694 666
695 ce = client_head; 667 ce = client_head;
696 while (NULL != ce) 668 while (NULL != ce)
669 {
670 if (ce->client == client)
697 { 671 {
698 if (ce->client == client) 672 GNUNET_SERVER_client_drop (ce->client);
699 { 673 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, ce);
700 GNUNET_SERVER_client_drop (ce->client); 674 GNUNET_free (ce);
701 GNUNET_CONTAINER_DLL_remove (client_head, 675 break;
702 client_tail,
703 ce);
704 GNUNET_free (ce);
705 break;
706 }
707 ce = ce->next;
708 } 676 }
677 ce = ce->next;
678 }
709 se = start; 679 se = start;
710 while (NULL != se) 680 while (NULL != se)
681 {
682 wen = se->we_head;
683 while (NULL != (we = wen))
711 { 684 {
712 wen = se->we_head; 685 wen = we->next;
713 while (NULL != (we = wen)) 686 if (we->client != client)
714 { 687 continue;
715 wen = we->next; 688 GNUNET_SERVER_client_drop (we->client);
716 if (we->client != client) 689 GNUNET_CONTAINER_DLL_remove (se->we_head, se->we_tail, we);
717 continue; 690 GNUNET_free (we);
718 GNUNET_SERVER_client_drop (we->client);
719 GNUNET_CONTAINER_DLL_remove (se->we_head,
720 se->we_tail,
721 we);
722 GNUNET_free (we);
723 }
724 se = se->next;
725 } 691 }
692 se = se->next;
693 }
726} 694}
727 695
728 696
@@ -747,13 +715,10 @@ run (void *cls,
747 cfg = c; 715 cfg = c;
748 GNUNET_SERVER_add_handlers (server, handlers); 716 GNUNET_SERVER_add_handlers (server, handlers);
749 nc = GNUNET_SERVER_notification_context_create (server, 16); 717 nc = GNUNET_SERVER_notification_context_create (server, 16);
750 GNUNET_SERVER_disconnect_notify (server, 718 GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
751 &handle_client_disconnect,
752 NULL);
753 load (server); 719 load (server);
754 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 720 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
755 &shutdown_task, 721 &shutdown_task, NULL);
756 NULL);
757} 722}
758 723
759 724
@@ -771,8 +736,7 @@ main (int argc, char *const *argv)
771 GNUNET_SERVICE_run (argc, 736 GNUNET_SERVICE_run (argc,
772 argv, 737 argv,
773 "statistics", 738 "statistics",
774 GNUNET_SERVICE_OPTION_NONE, 739 GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1;
775 &run, NULL)) ? 0 : 1;
776} 740}
777 741
778/* end of gnunet-service-statistics.c */ 742/* end of gnunet-service-statistics.c */