From fd1e6aa62201876b4cb9b0f983ad4f3d2ca8c900 Mon Sep 17 00:00:00 2001 From: Riccardo Zaglia Date: Fri, 16 Aug 2024 01:29:20 +0200 Subject: [PATCH 1/2] fix(server_core): :bug: Fix deadlock on button set init --- alvr/server_core/src/connection.rs | 4 ++++ alvr/server_core/src/input_mapping.rs | 26 +++++++++++++------------- alvr/server_core/src/lib.rs | 10 +++++++++- alvr/server_openvr/src/lib.rs | 8 ++++---- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/alvr/server_core/src/connection.rs b/alvr/server_core/src/connection.rs index 818503f78c..606b42b8a4 100644 --- a/alvr/server_core/src/connection.rs +++ b/alvr/server_core/src/connection.rs @@ -832,6 +832,7 @@ fn connection_pipeline( settings.headset.controllers.as_option().map(|config| { ButtonMappingManager::new_automatic( &HAND_GESTURE_BUTTON_SET, + &config.emulation_mode, &config.button_mapping_config, ) }); @@ -1087,6 +1088,7 @@ fn connection_pipeline( .get(&alvr_common::hash_string(QUEST_CONTROLLER_PROFILE_PATH)) .unwrap() .button_set, + &config.emulation_mode, &config.button_mapping_config, ) } @@ -1239,6 +1241,7 @@ fn connection_pipeline( } else { Some(ButtonMappingManager::new_automatic( &profile_info.button_set, + &config.emulation_mode, &config.button_mapping_config, )) } @@ -1274,6 +1277,7 @@ fn connection_pipeline( } else { Some(ButtonMappingManager::new_automatic( &input_ids, + &config.emulation_mode, &config.button_mapping_config, )) } diff --git a/alvr/server_core/src/input_mapping.rs b/alvr/server_core/src/input_mapping.rs index 9deaf39ea2..15f4bc6af4 100644 --- a/alvr/server_core/src/input_mapping.rs +++ b/alvr/server_core/src/input_mapping.rs @@ -1,5 +1,4 @@ -use crate::SERVER_DATA_MANAGER; -use alvr_common::{once_cell::sync::Lazy, settings_schema::Switch, *}; +use alvr_common::*; use alvr_packets::{ButtonEntry, ButtonValue}; use alvr_session::{ AutomaticButtonMappingConfig, BinaryToScalarStates, ButtonBindingTarget, ButtonMappingType, @@ -7,14 +6,10 @@ use alvr_session::{ }; use std::collections::{HashMap, HashSet}; -pub static REGISTERED_BUTTON_SET: Lazy> = Lazy::new(|| { - let data_manager_lock = SERVER_DATA_MANAGER.read(); - let Switch::Enabled(controllers_config) = &data_manager_lock.settings().headset.controllers - else { - return HashSet::new(); - }; - - match &controllers_config.emulation_mode { +pub fn registered_button_set( + controllers_emulation_mode: &ControllersEmulationMode, +) -> HashSet { + match &controllers_emulation_mode { ControllersEmulationMode::RiftSTouch | ControllersEmulationMode::Quest2Touch | ControllersEmulationMode::Quest3Plus => CONTROLLER_PROFILE_INFO @@ -38,7 +33,7 @@ pub static REGISTERED_BUTTON_SET: Lazy> = Lazy::new(|| { .map(|b| alvr_common::hash_string(b)) .collect(), } -}); +} pub struct BindingTarget { destination: u64, @@ -532,9 +527,14 @@ pub struct ButtonMappingManager { } impl ButtonMappingManager { - pub fn new_automatic(source: &HashSet, config: &AutomaticButtonMappingConfig) -> Self { + pub fn new_automatic( + source: &HashSet, + controllers_emulation_mode: &ControllersEmulationMode, + button_mapping_config: &AutomaticButtonMappingConfig, + ) -> Self { + let button_set = registered_button_set(controllers_emulation_mode); Self { - mappings: automatic_bindings(source, ®ISTERED_BUTTON_SET, config), + mappings: automatic_bindings(source, &button_set, button_mapping_config), binary_source_states: HashMap::new(), hysteresis_states: HashMap::new(), } diff --git a/alvr/server_core/src/lib.rs b/alvr/server_core/src/lib.rs index 5090d330e5..10814021e5 100644 --- a/alvr/server_core/src/lib.rs +++ b/alvr/server_core/src/lib.rs @@ -13,7 +13,6 @@ mod tracking; mod web_server; pub use c_api::*; -pub use input_mapping::REGISTERED_BUTTON_SET; pub use logging_backend::init_logging; pub use tracking::get_hand_skeleton_offsets; @@ -157,6 +156,15 @@ pub fn settings() -> Settings { SERVER_DATA_MANAGER.read().settings().clone() } +pub fn registered_button_set() -> HashSet { + let data_manager = SERVER_DATA_MANAGER.read(); + if let Switch::Enabled(input_mapping) = &data_manager.settings().headset.controllers { + input_mapping::registered_button_set(&input_mapping.emulation_mode) + } else { + HashSet::new() + } +} + pub struct ServerCoreContext { lifecycle_state: Arc>, is_restarting: RelaxedAtomic, diff --git a/alvr/server_openvr/src/lib.rs b/alvr/server_openvr/src/lib.rs index 58dbc0a3ca..9ef4464b75 100644 --- a/alvr/server_openvr/src/lib.rs +++ b/alvr/server_openvr/src/lib.rs @@ -23,7 +23,7 @@ use alvr_common::{ }; use alvr_filesystem as afs; use alvr_packets::{ButtonValue, Haptics}; -use alvr_server_core::{ServerCoreContext, ServerCoreEvent, REGISTERED_BUTTON_SET}; +use alvr_server_core::{ServerCoreContext, ServerCoreEvent}; use alvr_session::{CodecType, ControllersConfig}; use std::{ ffi::{c_char, c_void, CString}, @@ -262,10 +262,10 @@ pub extern "C" fn register_buttons(device_id: u64) { device_id }; - for id in &*REGISTERED_BUTTON_SET { - if let Some(info) = BUTTON_INFO.get(id) { + for id in alvr_server_core::registered_button_set() { + if let Some(info) = BUTTON_INFO.get(&id) { if info.device_id == mapped_device_id { - unsafe { RegisterButton(device_id, *id) }; + unsafe { RegisterButton(device_id, id) }; } } else { error!("Cannot register unrecognized button ID {id}"); From 03d20dd99000c8bef94b85afee4d329e4dea4f8f Mon Sep 17 00:00:00 2001 From: Riccardo Zaglia Date: Fri, 16 Aug 2024 02:06:38 +0200 Subject: [PATCH 2/2] Don't pick up updated emulation_mode --- alvr/server_core/src/connection.rs | 78 ++++++++++++++++-------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/alvr/server_core/src/connection.rs b/alvr/server_core/src/connection.rs index 606b42b8a4..b4c1cecb13 100644 --- a/alvr/server_core/src/connection.rs +++ b/alvr/server_core/src/connection.rs @@ -1074,25 +1074,24 @@ fn connection_pipeline( let control_receive_thread = thread::spawn({ let ctx = Arc::clone(&ctx); - let mut controller_button_mapping_manager = server_data_lock - .settings() - .headset - .controllers - .as_option() - .map(|config| { - if let Some(mappings) = &config.button_mappings { - ButtonMappingManager::new_manual(mappings) - } else { - ButtonMappingManager::new_automatic( - &CONTROLLER_PROFILE_INFO - .get(&alvr_common::hash_string(QUEST_CONTROLLER_PROFILE_PATH)) - .unwrap() - .button_set, - &config.emulation_mode, - &config.button_mapping_config, - ) - } - }); + + let controllers_config = server_data_lock.settings().headset.controllers.as_option(); + let mut controller_button_mapping_manager = controllers_config.map(|config| { + if let Some(mappings) = &config.button_mappings { + ButtonMappingManager::new_manual(mappings) + } else { + ButtonMappingManager::new_automatic( + &CONTROLLER_PROFILE_INFO + .get(&alvr_common::hash_string(QUEST_CONTROLLER_PROFILE_PATH)) + .unwrap() + .button_set, + &config.emulation_mode, + &config.button_mapping_config, + ) + } + }); + let controllers_emulation_mode = + controllers_config.map(|config| config.emulation_mode.clone()); let disconnect_notif = Arc::clone(&disconnect_notif); let control_sender = Arc::clone(&control_sender); @@ -1231,23 +1230,26 @@ fn connection_pipeline( }; } ClientControlPacket::ActiveInteractionProfile { profile_id, .. } => { - controller_button_mapping_manager = - if let (Switch::Enabled(config), Some(profile_info)) = ( - &SERVER_DATA_MANAGER.read().settings().headset.controllers, + controller_button_mapping_manager = if let Switch::Enabled(config) = + &SERVER_DATA_MANAGER.read().settings().headset.controllers + { + if let Some(mappings) = &config.button_mappings { + Some(ButtonMappingManager::new_manual(mappings)) + } else if let (Some(profile_info), Some(emulation_mode)) = ( CONTROLLER_PROFILE_INFO.get(&profile_id), + &controllers_emulation_mode, ) { - if let Some(mappings) = &config.button_mappings { - Some(ButtonMappingManager::new_manual(mappings)) - } else { - Some(ButtonMappingManager::new_automatic( - &profile_info.button_set, - &config.emulation_mode, - &config.button_mapping_config, - )) - } + Some(ButtonMappingManager::new_automatic( + &profile_info.button_set, + emulation_mode, + &config.button_mapping_config, + )) } else { None - }; + } + } else { + None + }; } ClientControlPacket::Log { level, message } => { info!("Client {client_hostname}: [{level:?}] {message}") @@ -1275,11 +1277,13 @@ fn connection_pipeline( if let Some(mappings) = &config.button_mappings { Some(ButtonMappingManager::new_manual(mappings)) } else { - Some(ButtonMappingManager::new_automatic( - &input_ids, - &config.emulation_mode, - &config.button_mapping_config, - )) + controllers_emulation_mode.as_ref().map(|emulation_mode| { + ButtonMappingManager::new_automatic( + &input_ids, + emulation_mode, + &config.button_mapping_config, + ) + }) } } else { None