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);