- if (client->server == NULL)
- return; /* already disconnected */
- GNUNET_assert (client->my_receive != GNUNET_SCHEDULER_NO_TASK);
- client->receive_cancel (client->client_closure, client->my_receive);
- client->my_receive = GNUNET_SCHEDULER_NO_TASK;
- shutdown_incoming_processing (client);
+ struct GNUNET_SERVER_Client *prev;
+ struct GNUNET_SERVER_Client *pos;
+ struct GNUNET_SERVER_Handle *server;
+ struct NotifyList *n;
+ unsigned int rc;
+
+#if DEBUG_SERVER
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client is being disconnected from the server.\n");
+#endif
+ if (client->restart_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (client->server->sched,
+ client->restart_task);
+ client->restart_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (GNUNET_YES == client->receive_pending)
+ {
+ GNUNET_CONNECTION_receive_cancel (client->connection);
+ client->receive_pending = GNUNET_NO;
+ }
+
+ rc = client->reference_count;
+ if (client->server != NULL)
+ {
+ server = client->server;
+ client->server = NULL;
+ client->shutdown_now = GNUNET_YES;
+ prev = NULL;
+ pos = server->clients;
+ while ((pos != NULL) && (pos != client))
+ {
+ prev = pos;
+ pos = pos->next;
+ }
+ GNUNET_assert (pos != NULL);
+ if (prev == NULL)
+ server->clients = pos->next;
+ else
+ prev->next = pos->next;
+ if (client->restart_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (server->sched,
+ client->restart_task);
+ client->restart_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ n = server->disconnect_notify_list;
+ while (n != NULL)
+ {
+ n->callback (n->callback_cls, client);
+ n = n->next;
+ }
+ }
+ if (rc > 0)
+ {
+#if DEBUG_SERVER
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "RC still positive, not destroying everything.\n");
+#endif
+ return;
+ }
+ if (client->in_process_client_buffer == GNUNET_YES)
+ {
+#if DEBUG_SERVER
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Still processing inputs, not destroying everything.\n");
+#endif
+ return;
+ }
+
+ if (client->persist == GNUNET_YES)
+ GNUNET_CONNECTION_persist_ (client->connection);
+ GNUNET_CONNECTION_destroy (client->connection, GNUNET_NO);
+ GNUNET_SERVER_mst_destroy (client->mst);
+ GNUNET_free (client);