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.
This commit is contained in:
parent
a54dc8212f
commit
5b9c88693e
2 changed files with 45 additions and 4 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue