From 5b9c88693ea1b2d19f325ab6ff6c06119781a101 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sun, 31 Oct 2021 14:56:37 +0100 Subject: [PATCH] Wait using a condition variable in server Currently, server_stop() is called from the same thread as server_connect_to(), so interruption may never happen. This is a step to prepare executing the server from a dedicated thread. --- app/src/server.c | 45 +++++++++++++++++++++++++++++++++++++++++---- app/src/server.h | 4 ++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/app/src/server.c b/app/src/server.c index 1491052a..5ed1984c 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -367,7 +367,8 @@ connect_and_read_byte(sc_socket socket, uint16_t port) { } static sc_socket -connect_to_server(uint16_t port, uint32_t attempts, uint32_t delay) { +connect_to_server(struct server *server, uint32_t attempts, sc_tick delay) { + uint16_t port = server->local_port; do { LOGD("Remaining connection attempts: %d", (int) attempts); sc_socket socket = net_socket(); @@ -381,7 +382,20 @@ connect_to_server(uint16_t port, uint32_t attempts, uint32_t delay) { net_close(socket); } if (attempts) { - SDL_Delay(delay); + sc_mutex_lock(&server->mutex); + sc_tick deadline = sc_tick_now() + delay; + bool timed_out = false; + while (!server->stopped && !timed_out) { + timed_out = !sc_cond_timedwait(&server->cond_stopped, + &server->mutex, deadline); + } + bool stopped = server->stopped; + sc_mutex_unlock(&server->mutex); + + if (stopped) { + LOGI("Connection attempt stopped"); + break; + } } } while (--attempts > 0); return SC_INVALID_SOCKET; @@ -395,7 +409,23 @@ server_init(struct server *server, const struct server_params *params) { return false; } + ok = sc_mutex_init(&server->mutex); + if (!ok) { + LOGE("Could not create server mutex"); + server_params_destroy(&server->params); + return false; + } + + ok = sc_cond_init(&server->cond_stopped); + if (!ok) { + LOGE("Could not create server cond_stopped"); + sc_mutex_destroy(&server->mutex); + server_params_destroy(&server->params); + return false; + } + server->process = SC_PROCESS_NONE; + server->stopped = false; server->server_socket = SC_INVALID_SOCKET; server->video_socket = SC_INVALID_SOCKET; @@ -453,8 +483,8 @@ server_connect_to(struct server *server, struct server_info *info) { server->server_socket = SC_INVALID_SOCKET; } else { uint32_t attempts = 100; - uint32_t delay = 100; // ms - video_socket = connect_to_server(server->local_port, attempts, delay); + sc_tick delay = SC_TICK_FROM_MS(100); + video_socket = connect_to_server(server, attempts, delay); if (video_socket == SC_INVALID_SOCKET) { goto fail; } @@ -563,6 +593,11 @@ error: void server_stop(struct server *server) { + sc_mutex_lock(&server->mutex); + server->stopped = true; + sc_cond_signal(&server->cond_stopped); + sc_mutex_unlock(&server->mutex); + if (server->server_socket != SC_INVALID_SOCKET) { if (!net_interrupt(server->server_socket)) { LOGW("Could not interrupt server socket"); @@ -627,4 +662,6 @@ server_destroy(struct server *server) { } } server_params_destroy(&server->params); + sc_cond_destroy(&server->cond_stopped); + sc_mutex_destroy(&server->mutex); } diff --git a/app/src/server.h b/app/src/server.h index 42082fa9..5807c322 100644 --- a/app/src/server.h +++ b/app/src/server.h @@ -47,6 +47,10 @@ struct server { // alive only between start() and stop() struct sc_process_observer observer; + sc_mutex mutex; + sc_cond cond_stopped; + bool stopped; + sc_socket server_socket; // only used if !tunnel_forward sc_socket video_socket; sc_socket control_socket;