The open source OpenXR runtime
at main 142 lines 2.5 kB view raw
1// Copyright 2023, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Helper to implement @ref xrt_session. 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 * @ingroup aux_util 8 */ 9 10#include "util/u_system.h" 11#include "util/u_session.h" 12 13 14/* 15 * 16 * Helpers. 17 * 18 */ 19 20static inline struct u_session * 21u_session(struct xrt_session *xs) 22{ 23 return (struct u_session *)xs; 24} 25 26 27/* 28 * 29 * Member functions. 30 * 31 */ 32 33static xrt_result_t 34push_event(struct xrt_session_event_sink *xses, const union xrt_session_event *xse) 35{ 36 struct u_session *us = container_of(xses, struct u_session, sink); 37 38 u_session_event_push(us, xse); 39 40 return XRT_SUCCESS; 41} 42 43static xrt_result_t 44poll_events(struct xrt_session *xs, union xrt_session_event *out_xse) 45{ 46 struct u_session *us = u_session(xs); 47 48 u_session_event_pop(us, out_xse); 49 50 return XRT_SUCCESS; 51} 52 53static void 54destroy(struct xrt_session *xs) 55{ 56 struct u_session *us = u_session(xs); 57 58 struct u_session_event *event = us->events.ptr; 59 while (event) { 60 struct u_session_event *tmp = event->next; 61 free(event); 62 event = tmp; 63 } 64 65 us->events.ptr = NULL; 66 67 if (us->usys != NULL) { 68 u_system_remove_session(us->usys, &us->base, &us->sink); 69 } 70 71 free(xs); 72} 73 74 75/* 76 * 77 * 'Exported' functions. 78 * 79 */ 80 81struct u_session * 82u_session_create(struct u_system *usys) 83{ 84 struct u_session *us = U_TYPED_CALLOC(struct u_session); 85 86 // xrt_session fields. 87 us->base.poll_events = poll_events; 88 us->base.destroy = destroy; 89 90 // xrt_session_event_sink fields. 91 us->sink.push_event = push_event; 92 93 // u_session fields. 94 XRT_MAYBE_UNUSED int ret = os_mutex_init(&us->events.mutex); 95 assert(ret == 0); 96 us->usys = usys; 97 98 // If we got a u_system. 99 if (usys != NULL) { 100 u_system_add_session(usys, &us->base, &us->sink); 101 } 102 103 return us; 104} 105 106void 107u_session_event_push(struct u_session *us, const union xrt_session_event *xse) 108{ 109 struct u_session_event *use = U_TYPED_CALLOC(struct u_session_event); 110 use->xse = *xse; 111 112 os_mutex_lock(&us->events.mutex); 113 114 // Find the last slot. 115 struct u_session_event **slot = &us->events.ptr; 116 while (*slot != NULL) { 117 slot = &(*slot)->next; 118 } 119 120 *slot = use; 121 122 os_mutex_unlock(&us->events.mutex); 123} 124 125void 126u_session_event_pop(struct u_session *us, union xrt_session_event *out_xse) 127{ 128 U_ZERO(out_xse); 129 out_xse->type = XRT_SESSION_EVENT_NONE; 130 131 os_mutex_lock(&us->events.mutex); 132 133 if (us->events.ptr != NULL) { 134 struct u_session_event *use = us->events.ptr; 135 136 *out_xse = use->xse; 137 us->events.ptr = use->next; 138 free(use); 139 } 140 141 os_mutex_unlock(&us->events.mutex); 142}