*/
struct GNUNET_CLIENT_TransmitHandle *th;
- /**
- * Result of the operation
- */
- enum GNUNET_ARM_ProcessStatus confirmed;
-
};
service_shutdown_handler (void *cls, const struct GNUNET_MessageHeader *msg)
{
struct ShutdownContext *shutdown_ctx = cls;
- const struct GNUNET_ARM_ResultMessage *rmsg;
- if (msg == NULL)
+ if (NULL != msg)
{
- if (shutdown_ctx->cont != NULL)
- {
- /* shutdown is now complete, as we waited for the network disconnect... */
- shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_DOWN);
- }
+ /* We just expected a disconnect! Report the error and be done with it... */
+ GNUNET_break (0);
+ shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR);
GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task);
GNUNET_CLIENT_disconnect (shutdown_ctx->sock);
GNUNET_free (shutdown_ctx);
return;
}
- if (ntohs (msg->size) ==
- sizeof (struct GNUNET_ARM_ResultMessage))
- {
- rmsg = (const struct GNUNET_ARM_ResultMessage*) msg;
- shutdown_ctx->confirmed = (enum GNUNET_ARM_ProcessStatus) ntohl (rmsg->status);
- if (shutdown_ctx->confirmed != GNUNET_ARM_PROCESS_SHUTDOWN)
- {
- /* ARM is not shutting down, well, report the error and be done with it... */
- shutdown_ctx->cont (shutdown_ctx->cont_cls, shutdown_ctx->confirmed);
- GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task);
- GNUNET_CLIENT_disconnect (shutdown_ctx->sock);
- GNUNET_free (shutdown_ctx);
- return;
- }
- }
- GNUNET_CLIENT_receive (shutdown_ctx->sock, &service_shutdown_handler,
- shutdown_ctx, GNUNET_TIME_UNIT_FOREVER_REL);
+ if (NULL != shutdown_ctx->cont)
+ /* shutdown is now complete, as we waited for the network disconnect... */
+ shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_DOWN);
+ GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task);
+ GNUNET_CLIENT_disconnect (shutdown_ctx->sock);
+ GNUNET_free (shutdown_ctx);
}
shutdown_ctx->cont_cls = cont_cls;
shutdown_ctx->sock = sock;
shutdown_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
- shutdown_ctx->confirmed = GNUNET_ARM_PROCESS_COMMUNICATION_ERROR;
shutdown_ctx->th = GNUNET_CLIENT_notify_transmit_ready (sock,
sizeof (struct GNUNET_MessageHeader),
timeout, GNUNET_NO, &write_shutdown,
}
-/**
- * Transmit our shutdown acknowledgement to the client.
- *
- * @param cls the 'struct GNUNET_SERVER_Client'
- * @param size number of bytes available in buf
- * @param buf where to write the message
- * @return number of bytes written
- */
-static size_t
-transmit_shutdown_ack (void *cls, size_t size, void *buf)
-{
- struct GNUNET_SERVER_Client *client = cls;
- struct GNUNET_ARM_ResultMessage *msg;
-
- if (size < sizeof (struct GNUNET_ARM_ResultMessage))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Failed to transmit shutdown ACK.\n"));
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return 0; /* client disconnected */
- }
- /* Make the connection flushing for the purpose of ACK transmitting,
- * needed on W32 to ensure that the message is even received, harmless
- * on other platforms... */
- GNUNET_break (GNUNET_OK == GNUNET_SERVER_client_disable_corking (client));
- msg = (struct GNUNET_ARM_ResultMessage *) buf;
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_ARM_RESULT);
- msg->header.size = htons (sizeof (struct GNUNET_ARM_ResultMessage));
- msg->status = htonl ((uint32_t) GNUNET_ARM_PROCESS_SHUTDOWN);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- GNUNET_SERVER_client_drop (client);
- return sizeof (struct GNUNET_ARM_ResultMessage);
-}
-
-
/**
* Handler for SHUTDOWN message.
*
const struct GNUNET_MessageHeader *message)
{
GNUNET_SCHEDULER_shutdown ();
- GNUNET_SERVER_client_keep (client);
- GNUNET_SERVER_notify_transmit_ready (client,
- sizeof (struct GNUNET_ARM_ResultMessage),
- GNUNET_TIME_UNIT_FOREVER_REL,
- &transmit_shutdown_ack, client);
GNUNET_SERVER_client_persist_ (client);
}
+
/**
* Signal handler called for SIGCHLD. Triggers the
* respective handler by writing to the trigger pipe.
#include "gnunet_time_lib.h"
-static size_t
-transmit_shutdown_ack (void *cls, size_t size, void *buf)
-{
- struct GNUNET_SERVER_Client *client = cls;
- struct GNUNET_MessageHeader *msg;
-
- if (size < sizeof (struct GNUNET_MessageHeader))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Failed to transmit shutdown ACK.\n"));
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return 0; /* client disconnected */
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Transmitting shutdown ACK.\n"));
-
- msg = (struct GNUNET_MessageHeader *) buf;
- msg->type = htons (GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN);
- msg->size = htons (sizeof (struct GNUNET_MessageHeader));
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- GNUNET_SERVER_client_drop (client);
- return sizeof (struct GNUNET_MessageHeader);
-}
-
/**
* Handler for SHUTDOWN message.
*
handle_shutdown (void *cls, struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message)
{
- GNUNET_SERVER_client_keep (client);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
_("Initiating shutdown as requested by client.\n"));
-
- GNUNET_SERVER_notify_transmit_ready (client,
- sizeof (struct GNUNET_MessageHeader),
- GNUNET_TIME_UNIT_FOREVER_REL,
- &transmit_shutdown_ack, client);
GNUNET_SERVER_client_persist_ (client);
GNUNET_SCHEDULER_shutdown ();
}
void
GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
{
+ struct GNUNET_SERVER_Handle *server = client->server;
struct GNUNET_SERVER_Client *prev;
struct GNUNET_SERVER_Client *pos;
- struct GNUNET_SERVER_Handle *server;
struct NotifyList *n;
unsigned int rc;
GNUNET_CONNECTION_receive_cancel (client->connection);
client->receive_pending = GNUNET_NO;
}
- server = client->server;
rc = client->reference_count;
- if (GNUNET_YES != client->shutdown_now)
+ if ( (GNUNET_YES != client->shutdown_now) &&
+ (NULL != server) )
{
client->shutdown_now = GNUNET_YES;
prev = NULL;
}
for (n = server->disconnect_notify_list_head; NULL != n; n = n->next)
n->callback (n->callback_cls, client);
+ if (NULL != server->mst_destroy)
+ server->mst_destroy (server->mst_cls, client->mst);
+ else
+ GNUNET_SERVER_mst_destroy (client->mst);
+ client->mst = NULL;
}
if (rc > 0)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
"RC still positive, not destroying everything.\n");
+ client->server = NULL;
return;
}
if (GNUNET_YES == client->in_process_client_buffer)
"Still processing inputs, not destroying everything.\n");
return;
}
-
if (GNUNET_YES == client->persist)
GNUNET_CONNECTION_persist_ (client->connection);
if (NULL != client->th.cth)
GNUNET_SERVER_notify_transmit_ready_cancel (&client->th);
GNUNET_CONNECTION_destroy (client->connection);
-
- if (NULL != server->mst_destroy)
- server->mst_destroy (server->mst_cls, client->mst);
- else
- GNUNET_SERVER_mst_destroy (client->mst);
GNUNET_free (client);
/* we might be in soft-shutdown, test if we're done */
- test_monitor_clients (server);
+ if (NULL != server)
+ test_monitor_clients (server);
}
client->th.cth = NULL;
callback = client->th.callback;
client->th.callback = NULL;
+ client->last_activity = GNUNET_TIME_absolute_get ();
ret = callback (client->th.callback_cls, size, buf);
- if (ret > 0)
- client->last_activity = GNUNET_TIME_absolute_get ();
return ret;
}