The open source OpenXR runtime

u/system: Rafactor u_system to be usable as a base class

Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2398>

+61 -9
+1
doc/changes/auxiliary/mr.2398.md
··· 1 + u/system: Make the system re-usable by other code.
+33 -8
src/xrt/auxiliary/util/u_system.c
··· 1 1 // Copyright 2023, Collabora, Ltd. 2 + // Copyright 2024-2025, NVIDIA CORPORATION. 2 3 // SPDX-License-Identifier: BSL-1.0 3 4 /*! 4 5 * @file ··· 91 92 { 92 93 struct u_system *usys = u_system(xsys); 93 94 94 - if (usys->sessions.count > 0) { 95 - U_LOG_E("Number of sessions not zero, things will crash!"); 96 - } 95 + // Use shared fini function. 96 + u_system_fini(usys); 97 97 98 - free(usys->sessions.pairs); 99 98 free(usys); 100 99 } 101 100 ··· 111 110 { 112 111 struct u_system *usys = U_TYPED_CALLOC(struct u_system); 113 112 113 + // Use init function, then add the common destroy function. 114 + if (!u_system_init(usys, destroy)) { 115 + free(usys); 116 + return NULL; 117 + } 118 + 119 + return usys; 120 + } 121 + 122 + bool 123 + u_system_init(struct u_system *usys, void (*destroy_fn)(struct xrt_system *)) 124 + { 114 125 // xrt_system fields. 115 126 usys->base.create_session = create_session; 116 - usys->base.destroy = destroy; 127 + usys->base.destroy = destroy_fn; 117 128 118 129 // xrt_session_event_sink fields. 119 130 usys->broadcast.push_event = push_event; ··· 122 133 usys->sessions.pairs = U_TYPED_ARRAY_CALLOC(struct u_system_session_pair, usys->sessions.capacity); 123 134 if (usys->sessions.pairs == NULL) { 124 135 U_LOG_E("Failed to allocate session array"); 125 - free(usys); 126 - return NULL; 136 + return false; 127 137 } 128 138 129 139 // u_system fields. 130 140 XRT_MAYBE_UNUSED int ret = os_mutex_init(&usys->sessions.mutex); 131 141 assert(ret == 0); 132 142 133 - return usys; 143 + return true; 144 + } 145 + 146 + void 147 + u_system_fini(struct u_system *usys) 148 + { 149 + // Just in case, should never happen. 150 + if (usys->sessions.count > 0) { 151 + U_LOG_E("Number of sessions not zero, things will crash!"); 152 + } 153 + 154 + free(usys->sessions.pairs); 155 + usys->sessions.count = 0; 156 + 157 + // Mutex needs to be destroyed. 158 + os_mutex_destroy(&usys->sessions.mutex); 134 159 } 135 160 136 161 void
+27 -1
src/xrt/auxiliary/util/u_system.h
··· 1 1 // Copyright 2023, Collabora, Ltd. 2 + // Copyright 2024-2025, NVIDIA CORPORATION. 2 3 // SPDX-License-Identifier: BSL-1.0 3 4 /*! 4 5 * @file ··· 68 69 }; 69 70 70 71 /*! 71 - * Create a @ref u_system. 72 + * Create a @ref u_system, creates a fully working system. Objects wishing to 73 + * use @ref u_system as a parent class should use @ref u_system_init. 72 74 * 73 75 * @public @memberof u_system 74 76 * @ingroup aux_util 77 + * @see u_system_init 75 78 */ 76 79 struct u_system * 77 80 u_system_create(void); 81 + 82 + /*! 83 + * Inits a @ref u_system struct when used as a parent class, only to be used 84 + * by base class. Not needed to be called if created by @ref u_system_create. 85 + * 86 + * @protected @memberof u_system 87 + * @ingroup aux_util 88 + */ 89 + bool 90 + u_system_init(struct u_system *usys, void (*destroy_fn)(struct xrt_system *)); 91 + 92 + /*! 93 + * Finalizes a @ref u_system struct when used as a parent class, only to be used 94 + * by base class. This will not free the @ref u_system pointer itself but will 95 + * free any resources created by the default implementation functions. Not 96 + * needed to be called if created by @ref u_system_create, instead use 97 + * xrt_system::destroy. 98 + * 99 + * @protected @memberof u_system 100 + * @ingroup aux_util 101 + */ 102 + void 103 + u_system_fini(struct u_system *usys); 78 104 79 105 /*! 80 106 * Add a @ref xrt_session to be tracked and to receive multiplexed events.