struct GNUNET_SERVER_Client *client;
uint64_t last_value;
-
+
uint32_t wid;
};
struct ClientEntry *prev;
struct GNUNET_SERVER_Client *client;
-
+
uint32_t max_wid;
};
static void
-inject_message (void *cls,
- void *client,
- const struct GNUNET_MessageHeader *msg)
+inject_message (void *cls, void *client, const struct GNUNET_MessageHeader *msg)
{
struct GNUNET_SERVER_Handle *server = cls;
if (fn == NULL)
return;
if ((0 != stat (fn, &sb)) || (sb.st_size == 0))
- {
- GNUNET_free (fn);
- return;
- }
- fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_READ,
- GNUNET_DISK_PERM_NONE);
+ {
+ GNUNET_free (fn);
+ return;
+ }
+ fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE);
if (!fh)
- {
- GNUNET_free (fn);
- return;
- }
+ {
+ GNUNET_free (fn);
+ return;
+ }
buf = GNUNET_DISK_file_map (fh, &mh, GNUNET_DISK_MAP_TYPE_READ, sb.st_size);
if (NULL == buf)
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "mmap", fn);
- GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh));
- GNUNET_free (fn);
- return;
- }
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "mmap", fn);
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh));
+ GNUNET_free (fn);
+ return;
+ }
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
_("Loading %llu bytes of statistics from `%s'\n"),
(unsigned long long) sb.st_size, fn);
- mst = GNUNET_SERVER_mst_create (&inject_message,
- server);
+ mst = GNUNET_SERVER_mst_create (&inject_message, server);
GNUNET_break (GNUNET_OK ==
- GNUNET_SERVER_mst_receive (mst,
- NULL,
- buf,
- sb.st_size,
- GNUNET_YES,
- GNUNET_NO));
+ GNUNET_SERVER_mst_receive (mst,
+ NULL,
+ buf,
+ sb.st_size, GNUNET_YES, GNUNET_NO));
GNUNET_SERVER_mst_destroy (mst);
GNUNET_break (GNUNET_OK == GNUNET_DISK_file_unmap (mh));
GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh));
* Write persistent statistics to disk.
*/
static void
-save ()
+save ()
{
struct StatsEntry *pos;
char *fn;
"statistics", "statistics.data", NULL);
if (fn != NULL)
fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_WRITE
- | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE,
- GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
+ | GNUNET_DISK_OPEN_CREATE |
+ GNUNET_DISK_OPEN_TRUNCATE,
+ GNUNET_DISK_PERM_USER_READ |
+ GNUNET_DISK_PERM_USER_WRITE);
total = 0;
while (NULL != (pos = start))
+ {
+ start = pos->next;
+ if ((pos->persistent) && (NULL != fh))
{
- start = pos->next;
- if ((pos->persistent) && (NULL != fh))
- {
- size = htons (pos->msg->header.size);
- if (size != GNUNET_DISK_file_write (fh, pos->msg, size))
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
- "write", fn);
- GNUNET_DISK_file_close (fh);
- fh = NULL;
- }
- else
- total += size;
- }
- GNUNET_free (pos);
- }
- if (NULL != fh)
- {
- GNUNET_DISK_file_close (fh);
- if (total == 0)
- GNUNET_break (0 == UNLINK (fn));
+ size = htons (pos->msg->header.size);
+ if (size != GNUNET_DISK_file_write (fh, pos->msg, size))
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn);
+ GNUNET_DISK_file_close (fh);
+ fh = NULL;
+ }
else
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Wrote %llu bytes of statistics to `%s'\n"), total, fn);
+ total += size;
}
+ GNUNET_free (pos);
+ }
+ if (NULL != fh)
+ {
+ GNUNET_DISK_file_close (fh);
+ if (total == 0)
+ GNUNET_break (0 == UNLINK (fn));
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ _("Wrote %llu bytes of statistics to `%s'\n"), total, fn);
+ }
GNUNET_free_non_null (fn);
}
* Transmit the given stats value.
*/
static void
-transmit (struct GNUNET_SERVER_Client *client,
- const struct StatsEntry *e)
+transmit (struct GNUNET_SERVER_Client *client, const struct StatsEntry *e)
{
struct GNUNET_STATISTICS_ReplyMessage *m;
size_t size;
size =
- sizeof (struct GNUNET_STATISTICS_ReplyMessage) + strlen (e->service) + 1 +
- strlen (e->name) + 1;
+ sizeof (struct GNUNET_STATISTICS_ReplyMessage) + strlen (e->service) + 1 +
+ strlen (e->name) + 1;
GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
m = GNUNET_malloc (size);
m->header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_VALUE);
#if DEBUG_STATISTICS
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Transmitting value for `%s:%s' (%d): %llu\n",
- e->service, e->name,
- e->persistent, e->value);
+ e->service, e->name, e->persistent, e->value);
#endif
- GNUNET_SERVER_notification_context_unicast (nc, client, &m->header, GNUNET_NO);
+ GNUNET_SERVER_notification_context_unicast (nc, client, &m->header,
+ GNUNET_NO);
GNUNET_free (m);
}
{
return ((0 == strlen (service)) ||
(0 == strcmp (service, e->service)))
- && ((0 == strlen (name)) || (0 == strcmp (name, e->name)));
+ && ((0 == strlen (name)) || (0 == strcmp (name, e->name)));
}
GNUNET_assert (client != NULL);
ce = client_head;
while (ce != NULL)
- {
- if (ce->client == client)
- return ce;
- ce = ce->next;
- }
+ {
+ if (ce->client == client)
+ return ce;
+ ce = ce->next;
+ }
ce = GNUNET_malloc (sizeof (struct ClientEntry));
ce->client = client;
GNUNET_SERVER_client_keep (client);
- GNUNET_CONTAINER_DLL_insert (client_head,
- client_tail,
- ce);
- GNUNET_SERVER_notification_context_add (nc,
- client);
+ GNUNET_CONTAINER_DLL_insert (client_head, client_tail, ce);
+ GNUNET_SERVER_notification_context_add (nc, client);
return ce;
}
size = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader);
if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
size, 2, &service, &name))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
#if DEBUG_STATISTICS
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received request for statistics on `%s:%s'\n",
#endif
pos = start;
while (pos != NULL)
- {
- if (matches (pos, service, name))
- transmit (client, pos);
- pos = pos->next;
- }
+ {
+ if (matches (pos, service, name))
+ transmit (client, pos);
+ pos = pos->next;
+ }
end.size = htons (sizeof (struct GNUNET_MessageHeader));
end.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_END);
- GNUNET_SERVER_notification_context_unicast (nc,
- client,
- &end,
- GNUNET_NO);
- GNUNET_SERVER_receive_done (client,
- GNUNET_OK);
+ GNUNET_SERVER_notification_context_unicast (nc, client, &end, GNUNET_NO);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
pos = se->we_head;
while (pos != NULL)
+ {
+ if (pos->last_value != se->value)
{
- if (pos->last_value != se->value)
- {
- wvm.header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE);
- wvm.header.size = htons (sizeof (struct GNUNET_STATISTICS_WatchValueMessage));
- wvm.flags = htonl (se->persistent ? GNUNET_STATISTICS_PERSIST_BIT : 0);
- wvm.wid = htonl (pos->wid);
- wvm.reserved = htonl (0);
- wvm.value = GNUNET_htonll (se->value);
- GNUNET_SERVER_notification_context_unicast (nc,
- pos->client,
- &wvm.header,
- GNUNET_NO);
- pos->last_value = se->value;
- }
- pos = pos->next;
+ wvm.header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE);
+ wvm.header.size =
+ htons (sizeof (struct GNUNET_STATISTICS_WatchValueMessage));
+ wvm.flags = htonl (se->persistent ? GNUNET_STATISTICS_PERSIST_BIT : 0);
+ wvm.wid = htonl (pos->wid);
+ wvm.reserved = htonl (0);
+ wvm.value = GNUNET_htonll (se->value);
+ GNUNET_SERVER_notification_context_unicast (nc,
+ pos->client,
+ &wvm.header, GNUNET_NO);
+ pos->last_value = se->value;
}
+ pos = pos->next;
+ }
}
/**
make_client_entry (client);
msize = ntohs (message->size);
if (msize < sizeof (struct GNUNET_STATISTICS_SetMessage))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
size = msize - sizeof (struct GNUNET_STATISTICS_SetMessage);
msg = (const struct GNUNET_STATISTICS_SetMessage *) message;
if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &msg[1],
size, 2, &service, &name))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
flags = ntohl (msg->flags);
value = GNUNET_ntohll (msg->value);
#if DEBUG_STATISTICS
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received request to update statistic on `%s:%s' (%u) to/by %llu\n",
- service, name,
- (unsigned int) flags,
- (unsigned long long) value);
+ service, name, (unsigned int) flags, (unsigned long long) value);
#endif
pos = start;
prev = NULL;
while (pos != NULL)
+ {
+ if (matches (pos, service, name))
{
- if (matches (pos, service, name))
+ if ((flags & GNUNET_STATISTICS_SETFLAG_RELATIVE) == 0)
+ {
+ changed = (pos->value != value);
+ pos->value = value;
+ }
+ else
+ {
+ delta = (int64_t) value;
+ if ((delta < 0) && (pos->value < -delta))
+ {
+ changed = (pos->value != 0);
+ pos->value = 0;
+ }
+ else
{
- if ((flags & GNUNET_STATISTICS_SETFLAG_RELATIVE) == 0)
- {
- changed = (pos->value != value);
- pos->value = value;
- }
- else
- {
- delta = (int64_t) value;
- if ((delta < 0) && (pos->value < -delta))
- {
- changed = (pos->value != 0);
- pos->value = 0;
- }
- else
- {
- changed = (delta != 0);
- GNUNET_break ((delta <= 0) ||
- (pos->value + delta > pos->value));
- pos->value += delta;
- }
- }
- pos->msg->value = GNUNET_htonll (pos->value);
- pos->msg->flags = msg->flags;
- pos->persistent =
- (0 != (flags & GNUNET_STATISTICS_SETFLAG_PERSISTENT));
- if (prev != NULL)
- {
- /* move to front for faster setting next time! */
- prev->next = pos->next;
- pos->next = start;
- start = pos;
- }
+ changed = (delta != 0);
+ GNUNET_break ((delta <= 0) || (pos->value + delta > pos->value));
+ pos->value += delta;
+ }
+ }
+ pos->msg->value = GNUNET_htonll (pos->value);
+ pos->msg->flags = msg->flags;
+ pos->persistent = (0 != (flags & GNUNET_STATISTICS_SETFLAG_PERSISTENT));
+ if (prev != NULL)
+ {
+ /* move to front for faster setting next time! */
+ prev->next = pos->next;
+ pos->next = start;
+ start = pos;
+ }
#if DEBUG_STATISTICS
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Statistic `%s:%s' updated to value %llu.\n",
- service, name, pos->value);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Statistic `%s:%s' updated to value %llu.\n",
+ service, name, pos->value);
#endif
- if (changed)
- notify_change (pos);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
- prev = pos;
- pos = pos->next;
+ if (changed)
+ notify_change (pos);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
}
+ prev = pos;
+ pos = pos->next;
+ }
pos = GNUNET_malloc (sizeof (struct StatsEntry) + msize);
pos->next = start;
if (((flags & GNUNET_STATISTICS_SETFLAG_RELATIVE) == 0) ||
*/
static void
handle_watch (void *cls,
- struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
{
char *service;
char *name;
ce = make_client_entry (client);
msize = ntohs (message->size);
if (msize < sizeof (struct GNUNET_MessageHeader))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
size = msize - sizeof (struct GNUNET_MessageHeader);
if (size != GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
size, 2, &service, &name))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
#if DEBUG_STATISTICS
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received request to watch statistic on `%s:%s'\n",
#endif
pos = start;
while (pos != NULL)
- {
- if (matches (pos, service, name))
- break;
- pos = pos->next;
- }
+ {
+ if (matches (pos, service, name))
+ break;
+ pos = pos->next;
+ }
if (pos == NULL)
- {
- pos = GNUNET_malloc (sizeof (struct StatsEntry) +
- sizeof (struct GNUNET_STATISTICS_SetMessage) +
- size);
- pos->next = start;
- pos->uid = uidgen++;
- pos->msg = (void *) &pos[1];
- pos->msg->header.size = htons (sizeof (struct GNUNET_STATISTICS_SetMessage) +
- size);
- pos->msg->header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_SET);
- pos->service = (const char *) &pos->msg[1];
- slen = strlen (service) + 1;
- memcpy ((void*) pos->service, service, slen);
- pos->name = &pos->service[slen];
- memcpy ((void*) pos->name, name, strlen (name)+1);
- start = pos;
- }
+ {
+ pos = GNUNET_malloc (sizeof (struct StatsEntry) +
+ sizeof (struct GNUNET_STATISTICS_SetMessage) + size);
+ pos->next = start;
+ pos->uid = uidgen++;
+ pos->msg = (void *) &pos[1];
+ pos->msg->header.size =
+ htons (sizeof (struct GNUNET_STATISTICS_SetMessage) + size);
+ pos->msg->header.type = htons (GNUNET_MESSAGE_TYPE_STATISTICS_SET);
+ pos->service = (const char *) &pos->msg[1];
+ slen = strlen (service) + 1;
+ memcpy ((void *) pos->service, service, slen);
+ pos->name = &pos->service[slen];
+ memcpy ((void *) pos->name, name, strlen (name) + 1);
+ start = pos;
+ }
we = GNUNET_malloc (sizeof (struct WatchEntry));
we->client = client;
GNUNET_SERVER_client_keep (client);
we->wid = ce->max_wid++;
- GNUNET_CONTAINER_DLL_insert (pos->we_head,
- pos->we_tail,
- we);
+ GNUNET_CONTAINER_DLL_insert (pos->we_head, pos->we_tail, we);
if (pos->value != 0)
notify_change (pos);
- GNUNET_SERVER_receive_done (client,
- GNUNET_OK);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
* @param tc unused
*/
static void
-shutdown_task (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct ClientEntry *ce;
struct WatchEntry *we;
GNUNET_SERVER_notification_context_destroy (nc);
nc = NULL;
while (NULL != (ce = client_head))
- {
- GNUNET_SERVER_client_drop (ce->client);
- GNUNET_CONTAINER_DLL_remove (client_head,
- client_tail,
- ce);
- GNUNET_free (ce);
- }
+ {
+ GNUNET_SERVER_client_drop (ce->client);
+ GNUNET_CONTAINER_DLL_remove (client_head, client_tail, ce);
+ GNUNET_free (ce);
+ }
while (NULL != (se = start))
+ {
+ start = se->next;
+ while (NULL != (we = se->we_head))
{
- start = se->next;
- while (NULL != (we = se->we_head))
- {
- GNUNET_SERVER_client_drop (we->client);
- GNUNET_CONTAINER_DLL_remove (se->we_head,
- se->we_tail,
- we);
- GNUNET_free (we);
- }
- GNUNET_free (se);
+ GNUNET_SERVER_client_drop (we->client);
+ GNUNET_CONTAINER_DLL_remove (se->we_head, se->we_tail, we);
+ GNUNET_free (we);
}
+ GNUNET_free (se);
+ }
}
* @param client identification of the client
*/
static void
-handle_client_disconnect (void *cls,
- struct GNUNET_SERVER_Client
- * client)
+handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
{
struct ClientEntry *ce;
struct WatchEntry *we;
struct WatchEntry *wen;
struct StatsEntry *se;
-
+
ce = client_head;
while (NULL != ce)
+ {
+ if (ce->client == client)
{
- if (ce->client == client)
- {
- GNUNET_SERVER_client_drop (ce->client);
- GNUNET_CONTAINER_DLL_remove (client_head,
- client_tail,
- ce);
- GNUNET_free (ce);
- break;
- }
- ce = ce->next;
+ GNUNET_SERVER_client_drop (ce->client);
+ GNUNET_CONTAINER_DLL_remove (client_head, client_tail, ce);
+ GNUNET_free (ce);
+ break;
}
+ ce = ce->next;
+ }
se = start;
while (NULL != se)
+ {
+ wen = se->we_head;
+ while (NULL != (we = wen))
{
- wen = se->we_head;
- while (NULL != (we = wen))
- {
- wen = we->next;
- if (we->client != client)
- continue;
- GNUNET_SERVER_client_drop (we->client);
- GNUNET_CONTAINER_DLL_remove (se->we_head,
- se->we_tail,
- we);
- GNUNET_free (we);
- }
- se = se->next;
+ wen = we->next;
+ if (we->client != client)
+ continue;
+ GNUNET_SERVER_client_drop (we->client);
+ GNUNET_CONTAINER_DLL_remove (se->we_head, se->we_tail, we);
+ GNUNET_free (we);
}
+ se = se->next;
+ }
}
cfg = c;
GNUNET_SERVER_add_handlers (server, handlers);
nc = GNUNET_SERVER_notification_context_create (server, 16);
- GNUNET_SERVER_disconnect_notify (server,
- &handle_client_disconnect,
- NULL);
+ GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
load (server);
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
- &shutdown_task,
- NULL);
+ &shutdown_task, NULL);
}
GNUNET_SERVICE_run (argc,
argv,
"statistics",
- GNUNET_SERVICE_OPTION_NONE,
- &run, NULL)) ? 0 : 1;
+ GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1;
}
/* end of gnunet-service-statistics.c */