From 3a7bff77f225381a526f550ab2eedd8b2b88dd3b Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Thu, 19 Oct 2017 18:50:42 +1100 Subject: [PATCH] [client] added ivshmem_process thread and fixed shutdown behaviour --- client/ivshmem/ivshmem.c | 27 ++++++++++++++++++++++---- client/ivshmem/ivshmem.h | 7 ++++--- client/main.c | 42 +++++++++++++++++++++++++++++++++++----- 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/client/ivshmem/ivshmem.c b/client/ivshmem/ivshmem.c index 90693b7a..23f94a79 100644 --- a/client/ivshmem/ivshmem.c +++ b/client/ivshmem/ivshmem.c @@ -42,6 +42,7 @@ struct IVSHMEMClient struct IVSHMEM { bool connected; + bool shutdown; int socket; struct IVSHMEMServer server; struct IVSHMEMClient * clients; @@ -53,6 +54,7 @@ struct IVSHMEM struct IVSHMEM ivshmem = { .connected = false, + .shutdown = false, .socket = -1 }; @@ -69,6 +71,7 @@ void ivshmem_remove_client(struct IVSHMEMClient * client); bool ivshmem_connect(const char * unix_socket) { + ivshmem.shutdown = false; ivshmem.socket = socket(AF_UNIX, SOCK_STREAM, 0); if (ivshmem.socket < 0) { @@ -177,6 +180,8 @@ void ivshmem_cleanup() if (ivshmem.socket >= 0) { + ivshmem.shutdown = true; + shutdown(ivshmem.socket, SHUT_RDWR); close(ivshmem.socket); ivshmem.socket = -1; } @@ -186,7 +191,7 @@ void ivshmem_cleanup() // ============================================================================ -void ivshmem_close() +void ivshmem_disconnect() { if (!ivshmem.connected) { @@ -250,13 +255,15 @@ bool ivshmem_read_msg(int64_t * index, int * fd) int ret = recvmsg(ivshmem.socket, &msg, 0); if (ret < sizeof(*index)) { - DEBUG_ERROR("failed ot read message\n"); + if (!ivshmem.shutdown) + DEBUG_ERROR("failed to read message\n"); return false; } if (ret == 0) { - DEBUG_ERROR("lost connetion to server\n"); + if (!ivshmem.shutdown) + DEBUG_ERROR("lost connetion to server\n"); return false; } @@ -279,6 +286,17 @@ bool ivshmem_read_msg(int64_t * index, int * fd) return true; } +uint16_t ivshmem_get_id() +{ + if (!ivshmem.connected) + { + DEBUG_ERROR("not connected"); + return -1; + } + + return ivshmem.server.clientID; +} + // ============================================================================ void * ivshmem_get_map() @@ -378,7 +396,8 @@ bool ivshmem_process() if (!ivshmem_read_msg(&index, &fd)) { - DEBUG_ERROR("failed to read message"); + if (!ivshmem.shutdown) + DEBUG_ERROR("failed to read message"); return false; } diff --git a/client/ivshmem/ivshmem.h b/client/ivshmem/ivshmem.h index 738f72e2..ff7e92de 100644 --- a/client/ivshmem/ivshmem.h +++ b/client/ivshmem/ivshmem.h @@ -3,8 +3,9 @@ #include bool ivshmem_connect(const char * unix_socket); -void ivshmem_close(); +void ivshmem_disconnect(); bool ivshmem_process(); -void * ivshmem_get_map(); -size_t ivshmem_get_map_size(); \ No newline at end of file +uint16_t ivshmem_get_id(); +void * ivshmem_get_map(); +size_t ivshmem_get_map_size(); \ No newline at end of file diff --git a/client/main.c b/client/main.c index e8b8f20a..df0db640 100644 --- a/client/main.c +++ b/client/main.c @@ -327,13 +327,32 @@ int renderThread(void * unused) return 0; } +int ivshmemThread(void * arg) +{ + while(state.running) + if (!ivshmem_process()) + { + if (state.running) + { + state.running = false; + DEBUG_ERROR("failed to process ivshmem messages"); + } + break; + } + + return 0; +} + int spiceThread(void * arg) { while(state.running) if (!spice_process()) { - state.running = false; - DEBUG_ERROR("Failed to process spice messages"); + if (state.running) + { + state.running = false; + DEBUG_ERROR("failed to process spice messages"); + } break; } @@ -463,9 +482,10 @@ int main(int argc, char * argv[]) memset(&state, 0, sizeof(state)); state.running = true; - int shm_fd = 0; - SDL_Thread *t_spice = NULL; - SDL_Thread *t_event = NULL; + int shm_fd = 0; + SDL_Thread *t_ivshmem = NULL; + SDL_Thread *t_spice = NULL; + SDL_Thread *t_event = NULL; while(1) { @@ -475,6 +495,12 @@ int main(int argc, char * argv[]) break; } + if (!(t_ivshmem = SDL_CreateThread(ivshmemThread, "ivshmemThread", NULL))) + { + DEBUG_ERROR("ivshmem create thread failed"); + break; + } + state.shm = (struct KVMGFXHeader *)ivshmem_get_map(); if (!state.shm) { @@ -519,6 +545,12 @@ int main(int argc, char * argv[]) if (t_event) SDL_WaitThread(t_event, NULL); + // this needs to happen here to abort any waiting reads + // as ivshmem uses recvmsg which has no timeout + ivshmem_disconnect(); + if (t_ivshmem) + SDL_WaitThread(t_ivshmem, NULL); + if (t_spice) SDL_WaitThread(t_spice, NULL);