From ad6209f6ffb34e271f9b7cab3f6474871a173627 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Fri, 16 Feb 2018 11:11:07 +0100 Subject: [PATCH] Terminate the device process gracefully Call shutdown() on the device socket to make the device process finish its execution quickly and gracefully, without killing it. --- app/src/net.c | 4 ++++ app/src/net.h | 6 ++++++ app/src/scrcpy.c | 2 +- app/src/server.c | 17 ++++++++++------- .../com/genymobile/scrcpy/ScrCpyServer.java | 6 ++++-- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/app/src/net.c b/app/src/net.c index bfb513f3..e2f3feac 100644 --- a/app/src/net.c +++ b/app/src/net.c @@ -71,3 +71,7 @@ ssize_t net_send_all(socket_t socket, void *buf, size_t len) { } return w; } + +SDL_bool net_shutdown(socket_t socket, int how) { + return !shutdown(socket, how); +} diff --git a/app/src/net.h b/app/src/net.h index 8d8994de..08ea61c1 100644 --- a/app/src/net.h +++ b/app/src/net.h @@ -6,10 +6,14 @@ #ifdef __WINDOWS__ # include + #define SHUT_RD SD_RECEIVE + #define SHUT_WR SD_SEND + #define SHUT_RDWR SD_BOTH typedef SIZE_T size_t; typedef SSIZE_T ssize_t; typedef SOCKET socket_t; #else +# include # define INVALID_SOCKET -1 typedef int socket_t; #endif @@ -25,6 +29,8 @@ ssize_t net_recv(socket_t socket, void *buf, size_t len); ssize_t net_recv_all(socket_t socket, void *buf, size_t len); ssize_t net_send(socket_t socket, void *buf, size_t len); ssize_t net_send_all(socket_t socket, void *buf, size_t len); +// how is SHUT_RD (read), SHUT_WR (write) or SHUT_RDWR (both) +SDL_bool net_shutdown(socket_t socket, int how); void net_close(socket_t socket); #endif diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 5891658d..8c549d67 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -164,7 +164,7 @@ finally_destroy_controller: controller_destroy(&controller); finally_stop_decoder: decoder_stop(&decoder); - // kill the server before decoder_join() to wake up the decoder + // stop the server before decoder_join() to wake up the decoder server_stop(&server, serial); decoder_join(&decoder); finally_destroy_frames: diff --git a/app/src/server.c b/app/src/server.c index 0cb4f0e6..dfb522cc 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -7,6 +7,7 @@ #include "config.h" #include "log.h" +#include "net.h" #define SOCKET_NAME "scrcpy" @@ -56,12 +57,6 @@ static process_t execute_server(const char *serial, Uint16 max_size, Uint32 bit_ return adb_execute(serial, cmd, sizeof(cmd) / sizeof(cmd[0])); } -static void terminate_server(process_t server) { - if (!cmd_terminate(server)) { - LOGE("Could not terminate server: %s", strerror(errno)); - } -} - static socket_t listen_on_port(Uint16 port) { #define IPV4_LOCALHOST 0x7F000001 return net_listen(IPV4_LOCALHOST, port, 1); @@ -126,7 +121,15 @@ socket_t server_connect_to(struct server *server, const char *serial, Uint32 tim void server_stop(struct server *server, const char *serial) { SDL_assert(server->process != PROCESS_NONE); - terminate_server(server->process); + + if (server->device_socket != INVALID_SOCKET) { + // shutdown the socket to finish the device process gracefully + net_shutdown(server->device_socket, SHUT_RDWR); + } + + LOGD("Waiting the server to complete execution on the device..."); + cmd_simple_wait(server->process, NULL); // ignore exit code + LOGD("Server terminated"); if (server->adb_reverse_enabled) { // ignore failure diff --git a/server/src/main/java/com/genymobile/scrcpy/ScrCpyServer.java b/server/src/main/java/com/genymobile/scrcpy/ScrCpyServer.java index 9895c535..61f84451 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ScrCpyServer.java +++ b/server/src/main/java/com/genymobile/scrcpy/ScrCpyServer.java @@ -21,7 +21,8 @@ public final class ScrCpyServer { // synchronous screenEncoder.streamScreen(device, connection.getOutputStream()); } catch (IOException e) { - Ln.w("Screen streaming stopped"); + // this is expected on close + Ln.d("Screen streaming stopped"); } } } @@ -33,7 +34,8 @@ public final class ScrCpyServer { try { new EventController(device, connection).control(); } catch (IOException e) { - Ln.w("Event controller stopped"); + // this is expected on close + Ln.d("Event controller stopped"); } } }).start();