{
int error;
- state.base = NULL;
+ state.base = roa_table_create();
+ if (state.base == NULL)
+ return pr_enomem();
deltas_db_init(&state.deltas);
error = pthread_rwlock_init(&lock, NULL);
if (error) {
deltas_db_cleanup(&state.deltas, delta_destroy);
+ roa_table_put(state.base);
return pr_errno(error, "pthread_rwlock_init() errored");
}
/* TODO (next iteration) Support both RTR v0 and v1 */
#define RTR_VERSION_SUPPORTED RTR_V0
+/* TODO (urgent) this needs to be atomic */
volatile bool loop;
struct thread_node {
act.sa_flags = SA_SIGINFO;
act.sa_sigaction = signal_handler;
+ /* TODO is this really legal? @act might need to be global. */
error = sigaction(SIGINT, &act, NULL);
if (error) {
pr_errno(errno, "Error initializing signal handler");
return error;
}
+/* Wait for threads to end gracefully */
+static void
+wait_threads(void)
+{
+ struct thread_node *ptr;
+
+ loop = false;
+ while (!SLIST_EMPTY(&threads)) {
+ ptr = SLIST_FIRST(&threads);
+ SLIST_REMOVE_HEAD(&threads, next);
+ /* TODO interrupt then join? Is this legal? */
+ pthread_kill(ptr->tid, SIGINT);
+ pthread_join(ptr->tid, NULL);
+ free(ptr);
+ }
+}
+
/*
* Starts the server, using the current thread to listen for RTR client
* requests.
/* Server ready, start updates thread */
error = updates_daemon_start();
if (error)
- return error;
+ goto revert_server_socket;
/* Init global vars */
loop = true;
error = init_signal_handler();
if (error)
- return error;
-
- return handle_client_connections(server_fd);
-}
+ goto revert_updates_daemon;
-void
-rtr_cleanup(void)
-{
- struct thread_node *ptr;
+ error = handle_client_connections(server_fd);
+ wait_threads();
+revert_updates_daemon:
updates_daemon_destroy();
-
- /* Wait for threads to end gracefully */
- loop = false;
- while (!SLIST_EMPTY(&threads)) {
- ptr = SLIST_FIRST(&threads);
- SLIST_REMOVE_HEAD(&threads, next);
- pthread_kill(ptr->tid, SIGINT);
- pthread_join(ptr->tid, NULL);
- free(ptr);
- }
+revert_server_socket:
+ close(server_fd);
+ return error;
}