summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-05-11 13:49:16 +0000
committerChristian Grothoff <christian@grothoff.org>2011-05-11 13:49:16 +0000
commita4f87c40e74cfff2b369958e7f2532ad23b40900 (patch)
tree46908c715c26601dde0fc70be068f6995c2d1a7d /src
parent558d4638048c52a2c7b8d87e1c0708ff834b3c04 (diff)
more comprehensive error reporting
Diffstat (limited to 'src')
-rw-r--r--src/util/server.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/src/util/server.c b/src/util/server.c
index f586e4204..8bc1e0b56 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -169,6 +169,16 @@ struct GNUNET_SERVER_Client
GNUNET_SCHEDULER_TaskIdentifier restart_task;
/**
+ * Task that warns about missing calls to 'GNUNET_SERVER_receive_done'.
+ */
+ GNUNET_SCHEDULER_TaskIdentifier warn_task;
+
+ /**
+ * Time when the warn task was started.
+ */
+ struct GNUNET_TIME_Absolute warn_start;
+
+ /**
* Last activity on this socket (used to time it out
* if reference_count == 0).
*/
@@ -216,6 +226,11 @@ struct GNUNET_SERVER_Client
* be used in special cases!
*/
int persist;
+
+ /**
+ * Type of last message processed (for warn_no_receive_done).
+ */
+ uint16_t warn_type;
};
@@ -557,6 +572,29 @@ GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
/**
+ * Task run to warn about missing calls to 'GNUNET_SERVER_receive_done'.
+ *
+ * @param cls our 'struct GNUNET_SERVER_Client*' to process more requests from
+ * @param tc scheduler context (unused)
+ */
+static void
+warn_no_receive_done (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct GNUNET_SERVER_Client *client = cls;
+
+ client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+ &warn_no_receive_done,
+ client);
+ if (0 == (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Processing code for message of type %u did not call GNUNET_SERVER_receive_done after %llums\n"),
+ (unsigned int) client->warn_type,
+ (unsigned long long) GNUNET_TIME_absolute_get_duration (client->warn_start).rel_value);
+}
+
+
+/**
* Inject a message into the server, pretend it came
* from the specified client. Delivery of the message
* will happen instantly (if a handler is installed;
@@ -614,7 +652,17 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
return GNUNET_SYSERR;
}
if (sender != NULL)
- sender->suspended++;
+ {
+ if (0 == sender->suspended)
+ {
+ sender->warn_start = GNUNET_TIME_absolute_get ();
+ sender->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+ &warn_no_receive_done,
+ sender);
+ sender->warn_type = type;
+ }
+ sender->suspended++;
+ }
mh->callback (mh->callback_cls, sender, message);
found = GNUNET_YES;
}
@@ -1012,6 +1060,11 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
GNUNET_SCHEDULER_cancel (client->restart_task);
client->restart_task = GNUNET_SCHEDULER_NO_TASK;
}
+ if (client->warn_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (client->warn_task);
+ client->warn_task = GNUNET_SCHEDULER_NO_TASK;
+ }
if (GNUNET_YES == client->receive_pending)
{
GNUNET_CONNECTION_receive_cancel (client->connection);
@@ -1041,6 +1094,11 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
GNUNET_SCHEDULER_cancel (client->restart_task);
client->restart_task = GNUNET_SCHEDULER_NO_TASK;
}
+ if (client->warn_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (client->warn_task);
+ client->warn_task = GNUNET_SCHEDULER_NO_TASK;
+ }
n = server->disconnect_notify_list;
while (n != NULL)
{
@@ -1148,6 +1206,11 @@ GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success)
#endif
return;
}
+ if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
+ {
+ GNUNET_SCHEDULER_cancel (client->warn_task);
+ client->warn_task = GNUNET_SCHEDULER_NO_TASK;
+ }
if (client->in_process_client_buffer == GNUNET_YES)
{
#if DEBUG_SERVER