Skip to content

Commit

Permalink
Kill the server only after some delay
Browse files Browse the repository at this point in the history
Let the server terminate properly once all the sockets are closed.

If it does not terminate (this can happen if the device is asleep), then
kill it.

Fixes #1992 <#1992>
  • Loading branch information
rom1v committed Jan 1, 2021
1 parent 83910d3 commit 298f605
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
43 changes: 41 additions & 2 deletions app/src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "config.h"
#include "command.h"
#include "util/lock.h"
#include "util/log.h"
#include "util/net.h"
#include "util/str_util.h"
Expand Down Expand Up @@ -361,6 +362,19 @@ server_init(struct server *server) {
atomic_flag_clear_explicit(&server->server_socket_closed,
memory_order_relaxed);

server->mutex = SDL_CreateMutex();
if (!server->mutex) {
return false;
}

server->process_terminated_cond = SDL_CreateCond();
if (!server->process_terminated_cond) {
SDL_DestroyMutex(server->mutex);
return false;
}

server->process_terminated = false;

server->server_socket = INVALID_SOCKET;
server->video_socket = INVALID_SOCKET;
server->control_socket = INVALID_SOCKET;
Expand All @@ -387,6 +401,12 @@ run_wait_server(void *data) {
// unblocked by closesocket(). Therefore, call both (close_socket()).
close_socket(server->server_socket);
}

mutex_lock(server->mutex);
server->process_terminated = true;
cond_signal(server->process_terminated_cond);
mutex_unlock(server->mutex);

LOGD("Server terminated");
return 0;
}
Expand Down Expand Up @@ -510,17 +530,36 @@ server_stop(struct server *server) {

assert(server->process != PROCESS_NONE);

cmd_terminate(server->process);

if (server->tunnel_enabled) {
// ignore failure
disable_tunnel(server);
}

// Give some delay for the server to terminate properly
mutex_lock(server->mutex);
int r = 0;
if (!server->process_terminated) {
#define WATCHDOG_DELAY 2000
r = cond_wait_timeout(server->process_terminated_cond,
server->mutex,
WATCHDOG_DELAY);
}
mutex_unlock(server->mutex);

// After this delay, kill the server.
// On some devices, closing the sockets is not sufficient to wake up the
// blocking calls while the device is asleep.
if (r == SDL_MUTEX_TIMEDOUT) {
LOGW("Killing the server");
cmd_terminate(server->process);
}

SDL_WaitThread(server->wait_server_thread, NULL);
}

void
server_destroy(struct server *server) {
SDL_free(server->serial);
SDL_DestroyCond(server->process_terminated_cond);
SDL_DestroyMutex(server->mutex);
}
5 changes: 5 additions & 0 deletions app/src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ struct server {
process_t process;
SDL_Thread *wait_server_thread;
atomic_flag server_socket_closed;

SDL_mutex *mutex;
SDL_cond *process_terminated_cond;
bool process_terminated;

socket_t server_socket; // only used if !tunnel_forward
socket_t video_socket;
socket_t control_socket;
Expand Down

0 comments on commit 298f605

Please sign in to comment.