|
Monado OpenXR Runtime
|
IPC client thread shutdown and blocking I/O cancellation. More...
#include "server/ipc_server.h"#include "server/ipc_server_thread_shutdown.h"#include <sys/socket.h>
Functions | |
| static void | ipc_server_cancel_all_client_io (struct ipc_server *s) |
| Cancel any blocking I/O a client thread is sitting in. | |
| void | ipc_server_client_thread_set_running (struct ipc_server *s, struct ipc_thread *it) |
| Do not revive a starting thread that shutdown has already stopped. | |
| bool | ipc_server_client_thread_is_running (struct ipc_server *s, struct ipc_thread *it) |
| Read the loop state under the same lock used to stop or start it. | |
| void | ipc_server_stop_and_join_client_threads (struct ipc_server *s) |
| Stop and join any remaining per-client threads. | |
IPC client thread shutdown and blocking I/O cancellation.
|
static |
Cancel any blocking I/O a client thread is sitting in.
An idle epoll based client loop wakes up on its own timeout and so notices the thread entering STOPPING, but the Windows one blocks in ReadFile() with no timeout and would only notice once the client happens to send something. On every platform a handler can also block mid-message, on a client that never sends the rest of a payload or never reads a reply. Cancelling the pending I/O makes it fail so the thread can run its shutdown and be joined.
The client thread closes this handle in common_shutdown() while holding the global state lock, so take it here as well, otherwise we could cancel I/O on a handle that has just been closed and possibly reused.
References ipc_client_state::imc, and ipc_server::lock.
Referenced by ipc_server_stop_and_join_client_threads().
| bool ipc_server_client_thread_is_running | ( | struct ipc_server * | s, |
| struct ipc_thread * | it | ||
| ) |
Read the loop state under the same lock used to stop or start it.
References ipc_server::lock.
| void ipc_server_client_thread_set_running | ( | struct ipc_server * | s, |
| struct ipc_thread * | it | ||
| ) |
Do not revive a starting thread that shutdown has already stopped.
References ipc_server::lock.
| void ipc_server_stop_and_join_client_threads | ( | struct ipc_server * | s | ) |
Stop and join any remaining per-client threads.
Stop all client loops, wake blocking I/O, then join each thread once.
Client threads may still be inside common_shutdown(), which destroys each client's compositor and dereferences s->xsysd / s->xso. Joining them before teardown_all() destroys those resources avoids a race where a client thread locks a mutex that teardown has already freed (observed as an om->initialized assertion in multi_compositor_destroy).
Stop their loops before joining, then wake every thread blocked in client I/O with ipc_server_cancel_all_client_io. That covers the Windows loop's ReadFile() and handlers stuck mid-message on any platform.
Called from shutdown_clients() before the main loop returns, and again from teardown_all() as a fallback.
References ipc_server_cancel_all_client_io(), and ipc_server::lock.