From eb09fefd43178e43b93952ef5befb9a62693a89f Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Fri, 9 Feb 2018 15:18:09 +0100 Subject: [PATCH] Timeout the server socket connection Wait no more than 2 seconds for accepting the connection from the device, since it blocks the event loop, preventing to react to SIGTERM (Ctrl+C). --- app/src/netutil.c | 7 +++---- app/src/netutil.h | 2 +- app/src/scrcpy.c | 9 +++++---- app/src/server.c | 4 ++-- app/src/server.h | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/src/netutil.c b/app/src/netutil.c index b6d2fdf8..8270df49 100644 --- a/app/src/netutil.c +++ b/app/src/netutil.c @@ -4,7 +4,7 @@ // contrary to SDLNet_TCP_Send and SDLNet_TCP_Recv, SDLNet_TCP_Accept is non-blocking // so we need to block before calling it -TCPsocket server_socket_accept(TCPsocket server_socket) { +TCPsocket server_socket_accept(TCPsocket server_socket, Uint32 timeout_ms) { SDLNet_SocketSet set = SDLNet_AllocSocketSet(1); if (!set) { SDL_LogCritical(SDL_LOG_CATEGORY_SYSTEM, "Could not allocate socket set"); @@ -17,9 +17,8 @@ TCPsocket server_socket_accept(TCPsocket server_socket) { return NULL; } - // timeout is (2^32-1) milliseconds, this should be sufficient - if (SDLNet_CheckSockets(set, -1) != 1) { - SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Could not check socket"); + if (SDLNet_CheckSockets(set, timeout_ms) != 1) { + SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "No connection to accept"); SDLNet_FreeSocketSet(set); return NULL; } diff --git a/app/src/netutil.h b/app/src/netutil.h index aa903cdd..d0a3d2a8 100644 --- a/app/src/netutil.h +++ b/app/src/netutil.h @@ -4,6 +4,6 @@ #include // blocking accept on the server socket -TCPsocket server_socket_accept(TCPsocket server_socket); +TCPsocket server_socket_accept(TCPsocket server_socket, Uint32 timeout_ms); #endif diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 29ce87b5..afa3d485 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -111,10 +111,11 @@ SDL_bool scrcpy(const char *serial, Uint16 local_port, Uint16 max_size, Uint32 b goto finally_destroy_server; } - // to reduce startup time, we could be tempted to init other stuff before blocking here - // but we should not block after SDL_Init since it handles the signals (Ctrl+C) in its - // event loop: blocking could lead to deadlock - TCPsocket device_socket = server_connect_to(&server, serial); + // SDL initialization replace the signal handler for SIGTERM, so Ctrl+C is + // managed by the event loop. This blocking call blocks the event loop, so + // timeout the connection not to block indefinitely in case of SIGTERM. +#define SERVER_CONNECT_TIMEOUT_MS 2000 + TCPsocket device_socket = server_connect_to(&server, serial, SERVER_CONNECT_TIMEOUT_MS); if (!device_socket) { server_stop(&server, serial); ret = SDL_FALSE; diff --git a/app/src/server.c b/app/src/server.c index e3c4e997..7f74694a 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -98,9 +98,9 @@ SDL_bool server_start(struct server *server, const char *serial, Uint16 local_po return SDL_TRUE; } -TCPsocket server_connect_to(struct server *server, const char *serial) { +TCPsocket server_connect_to(struct server *server, const char *serial, Uint32 timeout_ms) { SDL_assert(server->server_socket); - server->device_socket = server_socket_accept(server->server_socket); + server->device_socket = server_socket_accept(server->server_socket, timeout_ms); // we don't need the server socket anymore SDLNet_TCP_Close(server->server_socket); diff --git a/app/src/server.h b/app/src/server.h index 3ba1af0b..3d877f0c 100644 --- a/app/src/server.h +++ b/app/src/server.h @@ -26,7 +26,7 @@ SDL_bool server_start(struct server *server, const char *serial, Uint16 local_po Uint16 max_size, Uint32 bit_rate); // block until the communication with the server is established -TCPsocket server_connect_to(struct server *server, const char *serial); +TCPsocket server_connect_to(struct server *server, const char *serial, Uint32 timeout_ms); // disconnect and kill the server process void server_stop(struct server *server, const char *serial);