/** * 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); }
/** * Destroy a host handle. Must only be called once everything * running on that host has been stopped. * * @param host handle to destroy */ void GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host) { struct RegisteredController *rc; uint32_t id; GNUNET_assert (host->id < host_list_size); GNUNET_assert (host_list[host->id] == host); host_list[host->id] = NULL; /* clear registered controllers list */ for (rc = host->rc_head; NULL != rc; rc = host->rc_head) { GNUNET_CONTAINER_DLL_remove (host->rc_head, host->rc_tail, rc); GNUNET_free (rc); } GNUNET_free_non_null ((char *) host->username); GNUNET_free_non_null ((char *) host->hostname); GNUNET_TESTBED_operation_queue_destroy_ (host->opq_parallel_overlay_connect_operations); GNUNET_CONFIGURATION_destroy (host->cfg); GNUNET_free (host); while (host_list_size >= HOST_LIST_GROW_STEP) { for (id = host_list_size - 1; id > host_list_size - HOST_LIST_GROW_STEP; id--) if (NULL != host_list[id]) break; if (id != host_list_size - HOST_LIST_GROW_STEP) break; if (NULL != host_list[id]) break; host_list_size -= HOST_LIST_GROW_STEP; } host_list = GNUNET_realloc (host_list, sizeof (struct GNUNET_TESTBED_Host *) * host_list_size); }
/** * Function to cancel an operation (release all associated resources). This can * be because of a call to "GNUNET_TESTBED_operation_cancel" (before the * operation generated an event) or AFTER the operation generated an event due * to a call to "GNUNET_TESTBED_operation_done". Thus it is not guaranteed that * a callback to the 'OperationStart' preceeds the call to 'OperationRelease'. * Implementations of this function are expected to clean up whatever state is * in 'cls' and release all resources associated with the operation. */ static void release_cb (void *cls) { switch (result) { case TEST_OP1_STARTED: GNUNET_assert (&op1 == cls); result = TEST_OP1_RELEASED; op1 = NULL; step_task = GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL); break; case TEST_OP2_STARTED: GNUNET_assert (&op2 == cls); result = TEST_OP2_RELEASED; GNUNET_assert (NULL == step_task); break; case TEST_OP3_STARTED: GNUNET_assert (&op3 == cls); result = TEST_OP3_RELEASED; GNUNET_assert (NULL == step_task); break; case TEST_OP4_STARTED: GNUNET_assert (&op4 == cls); result = TEST_OP4_RELEASED; GNUNET_assert (NULL == step_task); op5 = GNUNET_TESTBED_operation_create_ (&op5, &start_cb, &release_cb); GNUNET_TESTBED_operation_queue_insert2_ (q1, op5, 1); GNUNET_TESTBED_operation_begin_wait_ (op5); op6 = GNUNET_TESTBED_operation_create_ (&op6, &start_cb, &release_cb); GNUNET_TESTBED_operation_queue_insert2_ (q2, op6, 1); GNUNET_TESTBED_operation_begin_wait_ (op6); op7 = GNUNET_TESTBED_operation_create_ (&op7, &start_cb, &release_cb); GNUNET_TESTBED_operation_queue_insert2_ (q1, op7, 1); GNUNET_TESTBED_operation_queue_insert2_ (q2, op7, 1); GNUNET_TESTBED_operation_begin_wait_ (op7); break; case TEST_OP5_6_7_STARTED: result = TEST_OP5_RELEASED; op5 = NULL; GNUNET_TESTBED_operation_release_ (op6); break; case TEST_OP5_RELEASED: op6 = NULL; result = TEST_OP6_RELEASED; GNUNET_TESTBED_operation_inactivate_ (op7); step_task = GNUNET_SCHEDULER_add_now (&step, NULL); break; case TEST_OP8_WAITING: GNUNET_assert (&op7 == cls); op7 = NULL; result = TEST_OP7_RELEASED; break; case TEST_OP8_ACTIVE: result = TEST_OP8_RELEASED; op8 = NULL; break; case TEST_OP9_STARTED: GNUNET_assert (&op9 == cls); result = TEST_OP9_RELEASED; GNUNET_TESTBED_operation_queue_destroy_ (q1); GNUNET_TESTBED_operation_queue_destroy_ (q2); q1 = NULL; q2 = NULL; break; default: GNUNET_assert (0); } }