/** * Task to clean up and shutdown nicely * * @param cls NULL * @param tc the TaskContext from scheduler */ static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct MessageQueue *mq_entry; uint32_t id; shutdown_task_id = NULL; LOG_DEBUG ("Shutting down testbed service\n"); /* cleanup any remaining forwarded operations */ GST_clear_fopcq (); GST_free_lcfq (); GST_free_mctxq (); GST_free_occq (); GST_free_roccq (); GST_free_nccq (); GST_neighbour_list_clean(); GST_free_prcq (); /* Clear peer list */ GST_destroy_peers (); /* Clear route list */ GST_route_list_clear (); /* Clear GST_slave_list */ GST_slave_list_clear (); /* Clear host list */ for (id = 0; id < GST_host_list_size; id++) if (NULL != GST_host_list[id]) GNUNET_TESTBED_host_destroy (GST_host_list[id]); GNUNET_free_non_null (GST_host_list); if (NULL != GST_context) { GNUNET_free_non_null (GST_context->master_ip); if (NULL != GST_context->system) GNUNET_TESTING_system_destroy (GST_context->system, GNUNET_YES); GNUNET_SERVER_client_drop (GST_context->client); GNUNET_free (GST_context); GST_context = NULL; } if (NULL != transmit_handle) GNUNET_SERVER_notify_transmit_ready_cancel (transmit_handle); while (NULL != (mq_entry = mq_head)) { GNUNET_free (mq_entry->msg); GNUNET_SERVER_client_drop (mq_entry->client); GNUNET_CONTAINER_DLL_remove (mq_head, mq_tail, mq_entry); GNUNET_free (mq_entry); } GNUNET_free_non_null (hostname); /* Free hello cache */ GST_cache_clear (); GST_connection_pool_destroy (); GNUNET_TESTBED_operation_queue_destroy_ (GST_opq_openfds); GST_opq_openfds = NULL; GST_stats_destroy (); GST_barriers_destroy (); GNUNET_CONFIGURATION_destroy (GST_config); }
/** * Called whenever a client is disconnected. Frees our * resources associated with that client. * * @param cls closure * @param client identification of the client */ static void client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client) { struct TransportClient *tc; struct MonitoringClient *mc; struct ClientMessageQueueEntry *mqe; if (client == NULL) return; mc = lookup_monitoring_client (peer_monitoring_clients_head, client); if (mc != NULL) { GNUNET_CONTAINER_DLL_remove (peer_monitoring_clients_head, peer_monitoring_clients_tail, mc); GNUNET_free (mc); } mc = lookup_monitoring_client (val_monitoring_clients_head, client); if (mc != NULL) { GNUNET_CONTAINER_DLL_remove (val_monitoring_clients_head, val_monitoring_clients_tail, mc); GNUNET_free (mc); } tc = lookup_client (client); if (tc == NULL) return; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "Client %p disconnected, cleaning up.\n", tc); while (NULL != (mqe = tc->message_queue_head)) { GNUNET_CONTAINER_DLL_remove (tc->message_queue_head, tc->message_queue_tail, mqe); tc->message_count--; GNUNET_free (mqe); } GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, tc); if (tc->th != NULL) { GNUNET_SERVER_notify_transmit_ready_cancel (tc->th); tc->th = NULL; } GNUNET_break (0 == tc->message_count); GNUNET_free (tc); }
static void server_client_destroy_impl (struct GNUNET_MQ_Handle *mq, void *impl_state) { struct ServerClientSocketState *state = impl_state; if (NULL != state->th) { GNUNET_SERVER_notify_transmit_ready_cancel (state->th); state->th = NULL; } GNUNET_assert (NULL != mq); GNUNET_assert (NULL != state); GNUNET_SERVER_client_drop (state->client); GNUNET_free (state); }
/** * Free the provided ClientInfo struct. * * This function takes care to cancel any pending transmission requests * and discard all outstanding messages not delivered to the client yet * before freeing the ClientInfo struct itself. * * @param client_info pointer to a ClientInfo struct */ static void client_info_free (struct ClientInfo *client_info) { struct PendingMessage *pm; if (NULL != client_info->transmit_handle) { GNUNET_SERVER_notify_transmit_ready_cancel (client_info->transmit_handle); client_info->transmit_handle = NULL; } while (NULL != (pm = client_info->pending_head)) { GNUNET_CONTAINER_DLL_remove (client_info->pending_head, client_info->pending_tail, pm); GNUNET_free (pm->msg); GNUNET_free (pm); } GNUNET_CONTAINER_DLL_remove (client_head, client_tail, client_info); GNUNET_free (client_info); }
/** * Functions with this signature are called whenever a client * is disconnected on the network level. * * @param cls closure (NULL for dht) * @param client identification of the client; NULL * for the last call when the server is destroyed */ static void handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) { struct ClientList *pos; struct PendingMessage *reply; struct ClientMonitorRecord *monitor; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Local client %p disconnects\n", client); pos = find_active_client (client); GNUNET_CONTAINER_DLL_remove (client_head, client_tail, pos); if (pos->transmit_handle != NULL) GNUNET_SERVER_notify_transmit_ready_cancel (pos->transmit_handle); while (NULL != (reply = pos->pending_head)) { GNUNET_CONTAINER_DLL_remove (pos->pending_head, pos->pending_tail, reply); GNUNET_free (reply); } monitor = monitor_head; while (NULL != monitor) { if (monitor->client == pos) { struct ClientMonitorRecord *next; GNUNET_free_non_null (monitor->key); next = monitor->next; GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, monitor); GNUNET_free (monitor); monitor = next; } else monitor = monitor->next; } GNUNET_CONTAINER_multihashmap_iterate (forward_map, &remove_client_records, pos); GNUNET_free (pos); }