···24#include "shared/ipc_protocol.h"
25#include "shared/ipc_message_channel.h"
2627+#include "ipc_server_interface.h"
28+29#include <stdio.h>
3031···413414 struct os_mutex lock;
415 } global_state;
416+417+ /*!
418+ * Callbacks for server events.
419+ */
420+ const struct ipc_server_callbacks *callbacks;
421+422+ /*!
423+ * User data passed to callbacks.
424+ */
425+ void *callback_data;
426};
427428/*!
+18
src/xrt/ipc/server/ipc_server_interface.h
···73 * @param[in] data User data given passed into the main function.
74 */
75 void (*mainloop_leaving)(struct ipc_server *s, struct xrt_instance *xinst, void *data);
00000000000000000076};
7778/*!
···73 * @param[in] data User data given passed into the main function.
74 */
75 void (*mainloop_leaving)(struct ipc_server *s, struct xrt_instance *xinst, void *data);
76+77+ /*!
78+ * A new client has connected to the IPC server.
79+ *
80+ * param s The IPC server.
81+ * param client_id The ID of the newly connected client.
82+ * param data User data given passed into the main function.
83+ */
84+ void (*client_connected)(struct ipc_server *s, uint32_t client_id, void *data);
85+86+ /*!
87+ * A client has disconnected from the IPC server.
88+ *
89+ * param s The IPC server.
90+ * param client_id The ID of the newly connected client.
91+ * param data User data given passed into the main function.
92+ */
93+ void (*client_disconnected)(struct ipc_server *s, uint32_t client_id, void *data);
94};
9596/*!
+23-3
src/xrt/ipc/server/ipc_server_per_client_thread.c
···1// Copyright 2020-2023, Collabora, Ltd.
02// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
···200{
201 U_TRACE_SET_THREAD_NAME("IPC Client");
202203- IPC_INFO(ics->server, "Client %u connected", ics->client_state.id);
0000204205 // Claim the client fd.
206 int epoll_fd = setup_epoll(ics);
···231232 // Detect clients disconnecting gracefully.
233 if (ret > 0 && (event.events & EPOLLHUP) != 0) {
234- IPC_INFO(ics->server, "Client disconnected.");
235 break;
236 }
237···273274 close(epoll_fd);
275 epoll_fd = -1;
000000276277 // Following code is same for all platforms.
278 common_shutdown(ics);
···297{
298 U_TRACE_SET_THREAD_NAME("IPC Client");
299300- IPC_INFO(ics->server, "Client connected");
0000301302 while (ics->server->running) {
303 uint8_t buf[IPC_BUF_SIZE] = {0};
···353 break;
354 }
355 }
000000356357 // Following code is same for all platforms.
358 common_shutdown(ics);
···1// Copyright 2020-2023, Collabora, Ltd.
2+// Copyright 2025, NVIDIA CORPORATION.
3// SPDX-License-Identifier: BSL-1.0
4/*!
5 * @file
···201{
202 U_TRACE_SET_THREAD_NAME("IPC Client");
203204+ // Call the client connected callback.
205+ ics->server->callbacks->client_connected( //
206+ ics->server, //
207+ ics->client_state.id, //
208+ ics->server->callback_data); //
209210 // Claim the client fd.
211 int epoll_fd = setup_epoll(ics);
···236237 // Detect clients disconnecting gracefully.
238 if (ret > 0 && (event.events & EPOLLHUP) != 0) {
0239 break;
240 }
241···277278 close(epoll_fd);
279 epoll_fd = -1;
280+281+ // Call the client disconnected callback.
282+ ics->server->callbacks->client_disconnected( //
283+ ics->server, //
284+ ics->client_state.id, //
285+ ics->server->callback_data); //
286287 // Following code is same for all platforms.
288 common_shutdown(ics);
···307{
308 U_TRACE_SET_THREAD_NAME("IPC Client");
309310+ // Call the client connected callback.
311+ ics->server->callbacks->client_connected( //
312+ ics->server, //
313+ ics->client_state.id, //
314+ ics->server->callback_data); //
315316 while (ics->server->running) {
317 uint8_t buf[IPC_BUF_SIZE] = {0};
···367 break;
368 }
369 }
370+371+ // Call the client disconnected callback.
372+ ics->server->callbacks->client_disconnected( //
373+ ics->server, //
374+ ics->client_state.id, //
375+ ics->server->callback_data); //
376377 // Following code is same for all platforms.
378 common_shutdown(ics);
+24-2
src/xrt/ipc/server/ipc_server_process.c
···462}
463464static xrt_result_t
465-init_all(struct ipc_server *s, enum u_logging_level log_level, bool exit_on_disconnect)
0000466{
467 xrt_result_t xret = XRT_SUCCESS;
468 int ret;
469470 // First order of business set the log level.
471 s->log_level = log_level;
0000472473 // This should never fail.
474 ret = os_mutex_init(&s->global_state.lock);
···1074 */
1075 u_debug_gui_create(&ismi->udgci, &s->debug_gui);
10761077- xret = init_all(s, log_level, ismi->exit_on_disconnect);
1078 U_LOG_CHK_ONLY_PRINT(log_level, xret, "init_all");
1079 if (xret != XRT_SUCCESS) {
1080 // Propegate the failure.
···1148 // No-op
1149}
11500000000000001151int
1152ipc_server_main(int argc, char **argv, const struct ipc_server_main_info *ismi)
1153{
···1155 .init_failed = init_failed,
1156 .mainloop_entering = mainloop_entering,
1157 .mainloop_leaving = mainloop_leaving,
001158 };
11591160 return ipc_server_main_common(ismi, &callbacks, NULL);