aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-05-03 13:46:42 +0000
committerChristian Grothoff <christian@grothoff.org>2012-05-03 13:46:42 +0000
commit1f4c6f762971b5398c3d54a7dd0000194ca7edd9 (patch)
tree4ad3eeb2db1a1abe7f912fe37399597fc6cc0df7
parent5c66facab3dae1b9dd7d7ee12c72b3dd9c51429a (diff)
downloadgnunet-1f4c6f762971b5398c3d54a7dd0000194ca7edd9.tar.gz
gnunet-1f4c6f762971b5398c3d54a7dd0000194ca7edd9.zip
-towards fixing #2299
-rw-r--r--src/arm/arm_api.c40
-rw-r--r--src/arm/gnunet-service-arm.c41
-rw-r--r--src/arm/mockup-service.c30
-rw-r--r--src/util/server.c24
4 files changed, 23 insertions, 112 deletions
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c
index f2992b38a..d6b65e872 100644
--- a/src/arm/arm_api.c
+++ b/src/arm/arm_api.c
@@ -87,11 +87,6 @@ struct ShutdownContext
87 */ 87 */
88 struct GNUNET_CLIENT_TransmitHandle *th; 88 struct GNUNET_CLIENT_TransmitHandle *th;
89 89
90 /**
91 * Result of the operation
92 */
93 enum GNUNET_ARM_ProcessStatus confirmed;
94
95}; 90};
96 91
97 92
@@ -110,37 +105,23 @@ static void
110service_shutdown_handler (void *cls, const struct GNUNET_MessageHeader *msg) 105service_shutdown_handler (void *cls, const struct GNUNET_MessageHeader *msg)
111{ 106{
112 struct ShutdownContext *shutdown_ctx = cls; 107 struct ShutdownContext *shutdown_ctx = cls;
113 const struct GNUNET_ARM_ResultMessage *rmsg;
114 108
115 if (msg == NULL) 109 if (NULL != msg)
116 { 110 {
117 if (shutdown_ctx->cont != NULL) 111 /* We just expected a disconnect! Report the error and be done with it... */
118 { 112 GNUNET_break (0);
119 /* shutdown is now complete, as we waited for the network disconnect... */ 113 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR);
120 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_DOWN);
121 }
122 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); 114 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task);
123 GNUNET_CLIENT_disconnect (shutdown_ctx->sock); 115 GNUNET_CLIENT_disconnect (shutdown_ctx->sock);
124 GNUNET_free (shutdown_ctx); 116 GNUNET_free (shutdown_ctx);
125 return; 117 return;
126 } 118 }
127 if (ntohs (msg->size) == 119 if (NULL != shutdown_ctx->cont)
128 sizeof (struct GNUNET_ARM_ResultMessage)) 120 /* shutdown is now complete, as we waited for the network disconnect... */
129 { 121 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_DOWN);
130 rmsg = (const struct GNUNET_ARM_ResultMessage*) msg; 122 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task);
131 shutdown_ctx->confirmed = (enum GNUNET_ARM_ProcessStatus) ntohl (rmsg->status); 123 GNUNET_CLIENT_disconnect (shutdown_ctx->sock);
132 if (shutdown_ctx->confirmed != GNUNET_ARM_PROCESS_SHUTDOWN) 124 GNUNET_free (shutdown_ctx);
133 {
134 /* ARM is not shutting down, well, report the error and be done with it... */
135 shutdown_ctx->cont (shutdown_ctx->cont_cls, shutdown_ctx->confirmed);
136 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task);
137 GNUNET_CLIENT_disconnect (shutdown_ctx->sock);
138 GNUNET_free (shutdown_ctx);
139 return;
140 }
141 }
142 GNUNET_CLIENT_receive (shutdown_ctx->sock, &service_shutdown_handler,
143 shutdown_ctx, GNUNET_TIME_UNIT_FOREVER_REL);
144} 125}
145 126
146 127
@@ -225,7 +206,6 @@ arm_service_shutdown (struct GNUNET_CLIENT_Connection *sock,
225 shutdown_ctx->cont_cls = cont_cls; 206 shutdown_ctx->cont_cls = cont_cls;
226 shutdown_ctx->sock = sock; 207 shutdown_ctx->sock = sock;
227 shutdown_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); 208 shutdown_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
228 shutdown_ctx->confirmed = GNUNET_ARM_PROCESS_COMMUNICATION_ERROR;
229 shutdown_ctx->th = GNUNET_CLIENT_notify_transmit_ready (sock, 209 shutdown_ctx->th = GNUNET_CLIENT_notify_transmit_ready (sock,
230 sizeof (struct GNUNET_MessageHeader), 210 sizeof (struct GNUNET_MessageHeader),
231 timeout, GNUNET_NO, &write_shutdown, 211 timeout, GNUNET_NO, &write_shutdown,
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c
index ab9e7f281..663a8e51a 100644
--- a/src/arm/gnunet-service-arm.c
+++ b/src/arm/gnunet-service-arm.c
@@ -1048,41 +1048,6 @@ maint_child_death (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1048 1048
1049 1049
1050/** 1050/**
1051 * Transmit our shutdown acknowledgement to the client.
1052 *
1053 * @param cls the 'struct GNUNET_SERVER_Client'
1054 * @param size number of bytes available in buf
1055 * @param buf where to write the message
1056 * @return number of bytes written
1057 */
1058static size_t
1059transmit_shutdown_ack (void *cls, size_t size, void *buf)
1060{
1061 struct GNUNET_SERVER_Client *client = cls;
1062 struct GNUNET_ARM_ResultMessage *msg;
1063
1064 if (size < sizeof (struct GNUNET_ARM_ResultMessage))
1065 {
1066 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1067 _("Failed to transmit shutdown ACK.\n"));
1068 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1069 return 0; /* client disconnected */
1070 }
1071 /* Make the connection flushing for the purpose of ACK transmitting,
1072 * needed on W32 to ensure that the message is even received, harmless
1073 * on other platforms... */
1074 GNUNET_break (GNUNET_OK == GNUNET_SERVER_client_disable_corking (client));
1075 msg = (struct GNUNET_ARM_ResultMessage *) buf;
1076 msg->header.type = htons (GNUNET_MESSAGE_TYPE_ARM_RESULT);
1077 msg->header.size = htons (sizeof (struct GNUNET_ARM_ResultMessage));
1078 msg->status = htonl ((uint32_t) GNUNET_ARM_PROCESS_SHUTDOWN);
1079 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1080 GNUNET_SERVER_client_drop (client);
1081 return sizeof (struct GNUNET_ARM_ResultMessage);
1082}
1083
1084
1085/**
1086 * Handler for SHUTDOWN message. 1051 * Handler for SHUTDOWN message.
1087 * 1052 *
1088 * @param cls closure (refers to service) 1053 * @param cls closure (refers to service)
@@ -1094,14 +1059,10 @@ handle_shutdown (void *cls, struct GNUNET_SERVER_Client *client,
1094 const struct GNUNET_MessageHeader *message) 1059 const struct GNUNET_MessageHeader *message)
1095{ 1060{
1096 GNUNET_SCHEDULER_shutdown (); 1061 GNUNET_SCHEDULER_shutdown ();
1097 GNUNET_SERVER_client_keep (client);
1098 GNUNET_SERVER_notify_transmit_ready (client,
1099 sizeof (struct GNUNET_ARM_ResultMessage),
1100 GNUNET_TIME_UNIT_FOREVER_REL,
1101 &transmit_shutdown_ack, client);
1102 GNUNET_SERVER_client_persist_ (client); 1062 GNUNET_SERVER_client_persist_ (client);
1103} 1063}
1104 1064
1065
1105/** 1066/**
1106 * Signal handler called for SIGCHLD. Triggers the 1067 * Signal handler called for SIGCHLD. Triggers the
1107 * respective handler by writing to the trigger pipe. 1068 * respective handler by writing to the trigger pipe.
diff --git a/src/arm/mockup-service.c b/src/arm/mockup-service.c
index 6f90956db..d9896997b 100644
--- a/src/arm/mockup-service.c
+++ b/src/arm/mockup-service.c
@@ -29,30 +29,6 @@
29#include "gnunet_time_lib.h" 29#include "gnunet_time_lib.h"
30 30
31 31
32static size_t
33transmit_shutdown_ack (void *cls, size_t size, void *buf)
34{
35 struct GNUNET_SERVER_Client *client = cls;
36 struct GNUNET_MessageHeader *msg;
37
38 if (size < sizeof (struct GNUNET_MessageHeader))
39 {
40 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
41 _("Failed to transmit shutdown ACK.\n"));
42 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
43 return 0; /* client disconnected */
44 }
45
46 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Transmitting shutdown ACK.\n"));
47
48 msg = (struct GNUNET_MessageHeader *) buf;
49 msg->type = htons (GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN);
50 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
51 GNUNET_SERVER_receive_done (client, GNUNET_OK);
52 GNUNET_SERVER_client_drop (client);
53 return sizeof (struct GNUNET_MessageHeader);
54}
55
56/** 32/**
57 * Handler for SHUTDOWN message. 33 * Handler for SHUTDOWN message.
58 * 34 *
@@ -64,14 +40,8 @@ static void
64handle_shutdown (void *cls, struct GNUNET_SERVER_Client *client, 40handle_shutdown (void *cls, struct GNUNET_SERVER_Client *client,
65 const struct GNUNET_MessageHeader *message) 41 const struct GNUNET_MessageHeader *message)
66{ 42{
67 GNUNET_SERVER_client_keep (client);
68 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 43 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
69 _("Initiating shutdown as requested by client.\n")); 44 _("Initiating shutdown as requested by client.\n"));
70
71 GNUNET_SERVER_notify_transmit_ready (client,
72 sizeof (struct GNUNET_MessageHeader),
73 GNUNET_TIME_UNIT_FOREVER_REL,
74 &transmit_shutdown_ack, client);
75 GNUNET_SERVER_client_persist_ (client); 45 GNUNET_SERVER_client_persist_ (client);
76 GNUNET_SCHEDULER_shutdown (); 46 GNUNET_SCHEDULER_shutdown ();
77} 47}
diff --git a/src/util/server.c b/src/util/server.c
index 4c110a134..f92d2f1d0 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -1261,9 +1261,9 @@ GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
1261void 1261void
1262GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client) 1262GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
1263{ 1263{
1264 struct GNUNET_SERVER_Handle *server = client->server;
1264 struct GNUNET_SERVER_Client *prev; 1265 struct GNUNET_SERVER_Client *prev;
1265 struct GNUNET_SERVER_Client *pos; 1266 struct GNUNET_SERVER_Client *pos;
1266 struct GNUNET_SERVER_Handle *server;
1267 struct NotifyList *n; 1267 struct NotifyList *n;
1268 unsigned int rc; 1268 unsigned int rc;
1269 1269
@@ -1284,9 +1284,9 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
1284 GNUNET_CONNECTION_receive_cancel (client->connection); 1284 GNUNET_CONNECTION_receive_cancel (client->connection);
1285 client->receive_pending = GNUNET_NO; 1285 client->receive_pending = GNUNET_NO;
1286 } 1286 }
1287 server = client->server;
1288 rc = client->reference_count; 1287 rc = client->reference_count;
1289 if (GNUNET_YES != client->shutdown_now) 1288 if ( (GNUNET_YES != client->shutdown_now) &&
1289 (NULL != server) )
1290 { 1290 {
1291 client->shutdown_now = GNUNET_YES; 1291 client->shutdown_now = GNUNET_YES;
1292 prev = NULL; 1292 prev = NULL;
@@ -1313,11 +1313,17 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
1313 } 1313 }
1314 for (n = server->disconnect_notify_list_head; NULL != n; n = n->next) 1314 for (n = server->disconnect_notify_list_head; NULL != n; n = n->next)
1315 n->callback (n->callback_cls, client); 1315 n->callback (n->callback_cls, client);
1316 if (NULL != server->mst_destroy)
1317 server->mst_destroy (server->mst_cls, client->mst);
1318 else
1319 GNUNET_SERVER_mst_destroy (client->mst);
1320 client->mst = NULL;
1316 } 1321 }
1317 if (rc > 0) 1322 if (rc > 0)
1318 { 1323 {
1319 LOG (GNUNET_ERROR_TYPE_DEBUG, 1324 LOG (GNUNET_ERROR_TYPE_DEBUG,
1320 "RC still positive, not destroying everything.\n"); 1325 "RC still positive, not destroying everything.\n");
1326 client->server = NULL;
1321 return; 1327 return;
1322 } 1328 }
1323 if (GNUNET_YES == client->in_process_client_buffer) 1329 if (GNUNET_YES == client->in_process_client_buffer)
@@ -1326,20 +1332,15 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
1326 "Still processing inputs, not destroying everything.\n"); 1332 "Still processing inputs, not destroying everything.\n");
1327 return; 1333 return;
1328 } 1334 }
1329
1330 if (GNUNET_YES == client->persist) 1335 if (GNUNET_YES == client->persist)
1331 GNUNET_CONNECTION_persist_ (client->connection); 1336 GNUNET_CONNECTION_persist_ (client->connection);
1332 if (NULL != client->th.cth) 1337 if (NULL != client->th.cth)
1333 GNUNET_SERVER_notify_transmit_ready_cancel (&client->th); 1338 GNUNET_SERVER_notify_transmit_ready_cancel (&client->th);
1334 GNUNET_CONNECTION_destroy (client->connection); 1339 GNUNET_CONNECTION_destroy (client->connection);
1335
1336 if (NULL != server->mst_destroy)
1337 server->mst_destroy (server->mst_cls, client->mst);
1338 else
1339 GNUNET_SERVER_mst_destroy (client->mst);
1340 GNUNET_free (client); 1340 GNUNET_free (client);
1341 /* we might be in soft-shutdown, test if we're done */ 1341 /* we might be in soft-shutdown, test if we're done */
1342 test_monitor_clients (server); 1342 if (NULL != server)
1343 test_monitor_clients (server);
1343} 1344}
1344 1345
1345 1346
@@ -1377,9 +1378,8 @@ transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
1377 client->th.cth = NULL; 1378 client->th.cth = NULL;
1378 callback = client->th.callback; 1379 callback = client->th.callback;
1379 client->th.callback = NULL; 1380 client->th.callback = NULL;
1381 client->last_activity = GNUNET_TIME_absolute_get ();
1380 ret = callback (client->th.callback_cls, size, buf); 1382 ret = callback (client->th.callback_cls, size, buf);
1381 if (ret > 0)
1382 client->last_activity = GNUNET_TIME_absolute_get ();
1383 return ret; 1383 return ret;
1384} 1384}
1385 1385