Skip to content

Commit

Permalink
fix(server_core): 🐛 Fix deadlock on button set init (#2330)
Browse files Browse the repository at this point in the history
* fix(server_core): 🐛 Fix deadlock on button set init

* Don't pick up updated emulation_mode
  • Loading branch information
zmerp committed Sep 10, 2024
1 parent 7ab6db9 commit a36de81
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 52 deletions.
76 changes: 42 additions & 34 deletions alvr/server_core/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
});
Expand Down Expand Up @@ -1073,24 +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.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);
Expand Down Expand Up @@ -1229,22 +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.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}")
Expand Down Expand Up @@ -1272,10 +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.button_mapping_config,
))
controllers_emulation_mode.as_ref().map(|emulation_mode| {
ButtonMappingManager::new_automatic(
&input_ids,
emulation_mode,
&config.button_mapping_config,
)
})
}
} else {
None
Expand Down
26 changes: 13 additions & 13 deletions alvr/server_core/src/input_mapping.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
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,
ControllersEmulationMode, HysteresisThreshold, Range,
};
use std::collections::{HashMap, HashSet};

pub static REGISTERED_BUTTON_SET: Lazy<HashSet<u64>> = 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<u64> {
match &controllers_emulation_mode {
ControllersEmulationMode::RiftSTouch
| ControllersEmulationMode::Quest2Touch
| ControllersEmulationMode::Quest3Plus => CONTROLLER_PROFILE_INFO
Expand All @@ -38,7 +33,7 @@ pub static REGISTERED_BUTTON_SET: Lazy<HashSet<u64>> = Lazy::new(|| {
.map(|b| alvr_common::hash_string(b))
.collect(),
}
});
}

pub struct BindingTarget {
destination: u64,
Expand Down Expand Up @@ -532,9 +527,14 @@ pub struct ButtonMappingManager {
}

impl ButtonMappingManager {
pub fn new_automatic(source: &HashSet<u64>, config: &AutomaticButtonMappingConfig) -> Self {
pub fn new_automatic(
source: &HashSet<u64>,
controllers_emulation_mode: &ControllersEmulationMode,
button_mapping_config: &AutomaticButtonMappingConfig,
) -> Self {
let button_set = registered_button_set(controllers_emulation_mode);
Self {
mappings: automatic_bindings(source, &REGISTERED_BUTTON_SET, config),
mappings: automatic_bindings(source, &button_set, button_mapping_config),
binary_source_states: HashMap::new(),
hysteresis_states: HashMap::new(),
}
Expand Down
10 changes: 9 additions & 1 deletion alvr/server_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -157,6 +156,15 @@ pub fn settings() -> Settings {
SERVER_DATA_MANAGER.read().settings().clone()
}

pub fn registered_button_set() -> HashSet<u64> {
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<RwLock<LifecycleState>>,
is_restarting: RelaxedAtomic,
Expand Down
8 changes: 4 additions & 4 deletions alvr/server_openvr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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}");
Expand Down

0 comments on commit a36de81

Please sign in to comment.