aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
169 GNUNET_SCHEDULER_TaskIdentifier restart_task; 169 GNUNET_SCHEDULER_TaskIdentifier restart_task;
170 170
171 /** 171 /**
172 * Task that warns about missing calls to 'GNUNET_SERVER_receive_done'.
173 */
174 GNUNET_SCHEDULER_TaskIdentifier warn_task;
175
176 /**
177 * Time when the warn task was started.
178 */
179 struct GNUNET_TIME_Absolute warn_start;
180
181 /**
172 * Last activity on this socket (used to time it out 182 * Last activity on this socket (used to time it out
173 * if reference_count == 0). 183 * if reference_count == 0).
174 */ 184 */
@@ -216,6 +226,11 @@ struct GNUNET_SERVER_Client
216 * be used in special cases! 226 * be used in special cases!
217 */ 227 */
218 int persist; 228 int persist;
229
230 /**
231 * Type of last message processed (for warn_no_receive_done).
232 */
233 uint16_t warn_type;
219}; 234};
220 235
221 236
@@ -557,6 +572,29 @@ GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
557 572
558 573
559/** 574/**
575 * Task run to warn about missing calls to 'GNUNET_SERVER_receive_done'.
576 *
577 * @param cls our 'struct GNUNET_SERVER_Client*' to process more requests from
578 * @param tc scheduler context (unused)
579 */
580static void
581warn_no_receive_done (void *cls,
582 const struct GNUNET_SCHEDULER_TaskContext *tc)
583{
584 struct GNUNET_SERVER_Client *client = cls;
585
586 client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
587 &warn_no_receive_done,
588 client);
589 if (0 == (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
590 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
591 _("Processing code for message of type %u did not call GNUNET_SERVER_receive_done after %llums\n"),
592 (unsigned int) client->warn_type,
593 (unsigned long long) GNUNET_TIME_absolute_get_duration (client->warn_start).rel_value);
594}
595
596
597/**
560 * Inject a message into the server, pretend it came 598 * Inject a message into the server, pretend it came
561 * from the specified client. Delivery of the message 599 * from the specified client. Delivery of the message
562 * will happen instantly (if a handler is installed; 600 * will happen instantly (if a handler is installed;
@@ -614,7 +652,17 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
614 return GNUNET_SYSERR; 652 return GNUNET_SYSERR;
615 } 653 }
616 if (sender != NULL) 654 if (sender != NULL)
617 sender->suspended++; 655 {
656 if (0 == sender->suspended)
657 {
658 sender->warn_start = GNUNET_TIME_absolute_get ();
659 sender->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
660 &warn_no_receive_done,
661 sender);
662 sender->warn_type = type;
663 }
664 sender->suspended++;
665 }
618 mh->callback (mh->callback_cls, sender, message); 666 mh->callback (mh->callback_cls, sender, message);
619 found = GNUNET_YES; 667 found = GNUNET_YES;
620 } 668 }
@@ -1012,6 +1060,11 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
1012 GNUNET_SCHEDULER_cancel (client->restart_task); 1060 GNUNET_SCHEDULER_cancel (client->restart_task);
1013 client->restart_task = GNUNET_SCHEDULER_NO_TASK; 1061 client->restart_task = GNUNET_SCHEDULER_NO_TASK;
1014 } 1062 }
1063 if (client->warn_task != GNUNET_SCHEDULER_NO_TASK)
1064 {
1065 GNUNET_SCHEDULER_cancel (client->warn_task);
1066 client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1067 }
1015 if (GNUNET_YES == client->receive_pending) 1068 if (GNUNET_YES == client->receive_pending)
1016 { 1069 {
1017 GNUNET_CONNECTION_receive_cancel (client->connection); 1070 GNUNET_CONNECTION_receive_cancel (client->connection);
@@ -1041,6 +1094,11 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
1041 GNUNET_SCHEDULER_cancel (client->restart_task); 1094 GNUNET_SCHEDULER_cancel (client->restart_task);
1042 client->restart_task = GNUNET_SCHEDULER_NO_TASK; 1095 client->restart_task = GNUNET_SCHEDULER_NO_TASK;
1043 } 1096 }
1097 if (client->warn_task != GNUNET_SCHEDULER_NO_TASK)
1098 {
1099 GNUNET_SCHEDULER_cancel (client->warn_task);
1100 client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1101 }
1044 n = server->disconnect_notify_list; 1102 n = server->disconnect_notify_list;
1045 while (n != NULL) 1103 while (n != NULL)
1046 { 1104 {
@@ -1148,6 +1206,11 @@ GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client, int success)
1148#endif 1206#endif
1149 return; 1207 return;
1150 } 1208 }
1209 if (GNUNET_SCHEDULER_NO_TASK != client->warn_task)
1210 {
1211 GNUNET_SCHEDULER_cancel (client->warn_task);
1212 client->warn_task = GNUNET_SCHEDULER_NO_TASK;
1213 }
1151 if (client->in_process_client_buffer == GNUNET_YES) 1214 if (client->in_process_client_buffer == GNUNET_YES)
1152 { 1215 {
1153#if DEBUG_SERVER 1216#if DEBUG_SERVER