The open source OpenXR runtime

a/util,st/oxr: Fixes crash bug with XR_EXT_dpad_binding Crash occurs after multiple session runs with clients using `XR_EXT_dpad_binding`, this is was caused be not full deep cloning of interaction profiles with dpad_state

authored by

Korcan Hussein and committed by
Simon Zeni
d9ef028d cfa545b4

+68
+11
src/xrt/auxiliary/util/u_hashmap.cpp
··· 4 4 * @file 5 5 * @brief Hashmap for integer values header. 6 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 + * @author Korcan Hussein <korcan.hussein@collabora.com> 7 8 * @ingroup aux_util 8 9 */ 9 10 ··· 77 78 u_hashmap_int_empty(const struct u_hashmap_int *hmi) 78 79 { 79 80 return hmi->map.empty(); 81 + } 82 + 83 + void 84 + u_hashmap_int_for_each(const struct u_hashmap_int *hmi, u_hashmap_int_foreach_callback cb, void *priv_ctx) 85 + { 86 + if (hmi == NULL || cb == NULL) 87 + return; 88 + for (const auto &keyval : hmi->map) { 89 + cb(keyval.first, keyval.second, priv_ctx); 90 + } 80 91 } 81 92 82 93 extern "C" void
+12
src/xrt/auxiliary/util/u_hashmap.h
··· 4 4 * @file 5 5 * @brief Hashmap for integer values header. 6 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 + * @author Korcan Hussein <korcan.hussein@collabora.com> 7 8 * @ingroup aux_util 8 9 */ 9 10 ··· 25 26 struct u_hashmap_int; 26 27 27 28 typedef void (*u_hashmap_int_callback)(void *item, void *priv); 29 + typedef void (*u_hashmap_int_foreach_callback)(uint64_t key, const void *value, void *priv_ctx); 28 30 29 31 int 30 32 u_hashmap_int_create(struct u_hashmap_int **out_hashmap); ··· 46 48 */ 47 49 bool 48 50 u_hashmap_int_empty(const struct u_hashmap_int *hmi); 51 + 52 + /*! 53 + * iterators through each [key,item] pairs of hash map 54 + * @param hmi hash map to iterate 55 + * @param cb callback invoked for each [key,item] pair + a user context. 56 + * @param priv_ctx user provided context, passed into `cb` 57 + * @ingroup aux_util 58 + */ 59 + void 60 + u_hashmap_int_for_each(const struct u_hashmap_int *hmi, u_hashmap_int_foreach_callback cb, void *priv_ctx); 49 61 50 62 /*! 51 63 * First clear the hashmap and then call the given callback with each item that
+4
src/xrt/state_trackers/oxr/oxr_binding.c
··· 538 538 } 539 539 } 540 540 541 + const struct oxr_dpad_state empty_dpad_state = {.uhi = NULL}; 542 + dst_profile->dpad_state = empty_dpad_state; 543 + oxr_dpad_state_clone(&dst_profile->dpad_state, &src_profile->dpad_state); 544 + 541 545 return dst_profile; 542 546 } 543 547
+32
src/xrt/state_trackers/oxr/oxr_dpad.c
··· 4 4 * @file 5 5 * @brief Holds binding related functions. 6 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 + * @author Korcan Hussein <korcan.hussein@collabora.com> 7 8 * @ingroup oxr_main 8 9 */ 9 10 ··· 22 23 free(item); 23 24 } 24 25 26 + static void 27 + clone_oxr_dpad_entry(uint64_t key, const void *src_data, void *ctx) 28 + { 29 + assert(src_data != NULL && ctx != NULL); 30 + 31 + struct oxr_dpad_state *dst_dpad_state = (struct oxr_dpad_state *)ctx; 32 + const struct oxr_dpad_entry *src_dpad_entry = (const struct oxr_dpad_entry *)src_data; 33 + 34 + struct oxr_dpad_entry *dst_dpad_entry = oxr_dpad_state_get_or_add(dst_dpad_state, key); 35 + assert(dst_dpad_entry != NULL); 36 + 37 + memcpy(dst_dpad_entry, src_dpad_entry, sizeof(struct oxr_dpad_entry)); 38 + } 25 39 26 40 /* 27 41 * ··· 68 82 u_hashmap_int_destroy(&state->uhi); 69 83 } 70 84 } 85 + 86 + bool 87 + oxr_dpad_state_clone(struct oxr_dpad_state *dst_dpad_state, const struct oxr_dpad_state *src_dpad_state) 88 + { 89 + if (dst_dpad_state == NULL || src_dpad_state == NULL) { 90 + return false; 91 + } 92 + 93 + oxr_dpad_state_deinit(dst_dpad_state); 94 + assert(dst_dpad_state->uhi == NULL); 95 + 96 + if (!oxr_dpad_state_init(dst_dpad_state)) 97 + return false; 98 + 99 + u_hashmap_int_for_each(src_dpad_state->uhi, clone_oxr_dpad_entry, dst_dpad_state); 100 + 101 + return true; 102 + }
+9
src/xrt/state_trackers/oxr/oxr_objects.h
··· 676 676 void 677 677 oxr_dpad_state_deinit(struct oxr_dpad_state *state); 678 678 679 + /*! 680 + * Clones all oxr_dpad_state 681 + * @param dst_dpad_state destination of cloning 682 + * @param src_dpad_state source of cloning 683 + * @public @memberof oxr_dpad_state_clone 684 + */ 685 + bool 686 + oxr_dpad_state_clone(struct oxr_dpad_state *dst_dpad_state, const struct oxr_dpad_state *src_dpad_state); 687 + 679 688 680 689 /*! 681 690 * @}