diff options
Diffstat (limited to 'src/util/server.c')
-rw-r--r-- | src/util/server.c | 65 |
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 | */ | ||
580 | static void | ||
581 | warn_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 |