diff --git a/src/xrt/ipc/client/ipc_client_compositor.c b/src/xrt/ipc/client/ipc_client_compositor.c index 136b62ae5..2cd3d916b 100644 --- a/src/xrt/ipc/client/ipc_client_compositor.c +++ b/src/xrt/ipc/client/ipc_client_compositor.c @@ -662,6 +662,10 @@ ipc_compositor_destroy(struct xrt_compositor *xc) assert(icc->compositor_created); + IPC_ERROR(icc->ipc_c, "Called"); + + IPC_CALL_CHK(ipc_call_session_destroy(icc->ipc_c)); + icc->compositor_created = false; } diff --git a/src/xrt/ipc/server/ipc_server.h b/src/xrt/ipc/server/ipc_server.h index 422f9640e..f5296533a 100644 --- a/src/xrt/ipc/server/ipc_server.h +++ b/src/xrt/ipc/server/ipc_server.h @@ -374,6 +374,13 @@ ipc_server_update_state(struct ipc_server *s); void * ipc_server_client_thread(void *_cs); +/*! + * This destroyes the native compositor for this client and any extra objects + * created from it, like all of the swapchains. + */ +void +ipc_server_client_destroy_compositor(volatile struct ipc_client_state *ics); + /*! * @defgroup ipc_server_internals Server Internals * @brief These are only called by the platform-specific mainloop polling code. diff --git a/src/xrt/ipc/server/ipc_server_handler.c b/src/xrt/ipc/server/ipc_server_handler.c index 2ce9f94fb..5b3e786dc 100644 --- a/src/xrt/ipc/server/ipc_server_handler.c +++ b/src/xrt/ipc/server/ipc_server_handler.c @@ -103,6 +103,10 @@ ipc_handle_session_create(volatile struct ipc_client_state *ics, const struct xr struct xrt_compositor_native *xcn = NULL; + if (ics->xc != NULL) { + return XRT_ERROR_IPC_SESSION_ALREADY_CREATED; + } + xrt_result_t xret = xrt_syscomp_create_native_compositor(ics->server->xsysc, xsi, &xcn); if (xret != XRT_SUCCESS) { return xret; @@ -144,6 +148,20 @@ ipc_handle_session_end(volatile struct ipc_client_state *ics) return xrt_comp_end_session(ics->xc); } +xrt_result_t +ipc_handle_session_destroy(volatile struct ipc_client_state *ics) +{ + IPC_TRACE_MARKER(); + + if (ics->xc == NULL) { + return XRT_ERROR_IPC_SESSION_NOT_CREATED; + } + + ipc_server_client_destroy_compositor(ics); + + return XRT_SUCCESS; +} + xrt_result_t ipc_handle_compositor_get_info(volatile struct ipc_client_state *ics, struct xrt_compositor_info *out_info) { diff --git a/src/xrt/ipc/server/ipc_server_per_client_thread.c b/src/xrt/ipc/server/ipc_server_per_client_thread.c index 047641ed0..adafec590 100644 --- a/src/xrt/ipc/server/ipc_server_per_client_thread.c +++ b/src/xrt/ipc/server/ipc_server_per_client_thread.c @@ -124,12 +124,37 @@ client_loop(volatile struct ipc_client_state *ics) ipc_message_channel_close((struct ipc_message_channel *)&ics->imc); - ics->num_swapchains = 0; - ics->server->threads[ics->server_thread_index].state = IPC_THREAD_STOPPING; ics->server_thread_index = -1; memset((void *)&ics->client_state, 0, sizeof(struct ipc_app_state)); + os_mutex_unlock(&ics->server->global_state.lock); + + ipc_server_client_destroy_compositor(ics); + + // Should we stop the server when a client disconnects? + if (ics->server->exit_on_disconnect) { + ics->server->running = false; + } + + ipc_server_deactivate_session(ics); +} + + +/* + * + * 'Exported' functions. + * + */ + +void +ipc_server_client_destroy_compositor(volatile struct ipc_client_state *ics) +{ + // Multiple threads might be looking at these fields. + os_mutex_lock(&ics->server->global_state.lock); + + ics->num_swapchains = 0; + // Destroy all swapchains now. for (uint32_t j = 0; j < IPC_MAX_CLIENT_SWAPCHAINS; j++) { // Drop our reference, does NULL checking. Cast away volatile. @@ -142,22 +167,8 @@ client_loop(volatile struct ipc_client_state *ics) // Cast away volatile. xrt_comp_destroy((struct xrt_compositor **)&ics->xc); - - // Should we stop the server when a client disconnects? - if (ics->server->exit_on_disconnect) { - ics->server->running = false; - } - - ipc_server_deactivate_session(ics); } - -/* - * - * Entry point. - * - */ - void * ipc_server_client_thread(void *_ics) { diff --git a/src/xrt/ipc/shared/proto.json b/src/xrt/ipc/shared/proto.json index d069e39cd..8b27e7415 100644 --- a/src/xrt/ipc/shared/proto.json +++ b/src/xrt/ipc/shared/proto.json @@ -66,6 +66,8 @@ "session_end": {}, + "session_destroy": {}, + "compositor_get_info": { "out": [ {"name": "info", "type": "struct xrt_compositor_info"}