struct HandlerList *handlers;
/**
- * List of our current clients.
+ * Head of list of our current clients.
*/
- struct GNUNET_SERVER_Client *clients;
+ struct GNUNET_SERVER_Client *clients_head;
+
+ /**
+ * Head of list of our current clients.
+ */
+ struct GNUNET_SERVER_Client *clients_tail;
/**
* Head of linked list of functions to call on disconnects by clients.
{
/**
- * This is a linked list.
+ * This is a doubly linked list.
*/
struct GNUNET_SERVER_Client *next;
+ /**
+ * This is a doubly linked list.
+ */
+ struct GNUNET_SERVER_Client *prev;
+
/**
* Processing of incoming data.
*/
int in_process_client_buffer;
/**
- * We're about to close down this client due to some serious
- * error.
+ * We're about to close down this client.
*/
int shutdown_now;
static struct GNUNET_NETWORK_Handle *
open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
{
- const static int on = 1;
+ static int on = 1;
struct GNUNET_NETWORK_Handle *sock;
uint16_t port;
int eno;
if (GNUNET_YES != server->in_soft_shutdown)
return;
- for (client = server->clients; NULL != client; client = client->next)
+ for (client = server->clients_head; NULL != client; client = client->next)
if (GNUNET_NO == client->is_monitor)
return; /* not done yet */
server->in_soft_shutdown = GNUNET_SYSERR;
GNUNET_free (server->listen_sockets);
server->listen_sockets = NULL;
}
- while (NULL != server->clients)
- GNUNET_SERVER_client_disconnect (server->clients);
+ while (NULL != server->clients_head)
+ GNUNET_SERVER_client_disconnect (server->clients_head);
while (NULL != (hpos = server->handlers))
{
server->handlers = hpos->next;
sender->in_process_client_buffer = GNUNET_YES;
ret = GNUNET_SERVER_inject (server, sender, message);
sender->in_process_client_buffer = GNUNET_NO;
- if (GNUNET_OK != ret)
+ if ( (GNUNET_OK != ret) || (GNUNET_YES == sender->shutdown_now) )
GNUNET_SERVER_client_disconnect (sender);
}
client->reference_count = 1;
client->server = server;
client->last_activity = GNUNET_TIME_absolute_get ();
- client->next = server->clients;
client->idle_timeout = server->idle_timeout;
- server->clients = client;
+ GNUNET_CONTAINER_DLL_insert (server->clients_head,
+ server->clients_tail,
+ client);
if (NULL != server->mst_create)
client->mst =
server->mst_create (server->mst_cls, client);
else
client->mst =
GNUNET_SERVER_mst_create (&client_message_tokenizer_callback, server);
+ GNUNET_assert (NULL != client->mst);
client->receive_pending = GNUNET_YES;
GNUNET_CONNECTION_receive (client->connection,
GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
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 NotifyList *n;
LOG (GNUNET_ERROR_TYPE_DEBUG,
GNUNET_CONNECTION_receive_cancel (client->connection);
client->receive_pending = GNUNET_NO;
}
-
+ client->shutdown_now = GNUNET_YES;
client->reference_count++; /* make sure nobody else clean up client... */
- if ( (GNUNET_YES != client->shutdown_now) &&
+ if ( (NULL != client->mst) &&
(NULL != server) )
{
- client->shutdown_now = GNUNET_YES;
- prev = NULL;
- pos = server->clients;
- while ((NULL != pos) && (pos != client))
- {
- prev = pos;
- pos = pos->next;
- }
- GNUNET_assert (NULL != pos);
- if (NULL == prev)
- server->clients = pos->next;
- else
- prev->next = pos->next;
+ GNUNET_CONTAINER_DLL_remove (server->clients_head,
+ server->clients_tail,
+ client);
if (GNUNET_SCHEDULER_NO_TASK != client->restart_task)
{
GNUNET_SCHEDULER_cancel (client->restart_task);
GNUNET_SCHEDULER_cancel (client->warn_task);
client->warn_task = GNUNET_SCHEDULER_NO_TASK;
}
- 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;
+ for (n = server->disconnect_notify_list_head; NULL != n; n = n->next)
+ n->callback (n->callback_cls, client);
}
client->reference_count--;
if (client->reference_count > 0)