rawinput: avoid deadlock when binding analog axis as a button (#809)

## Link to GitHub Issue or related Pull Request, if one exists
Regressed by #793

## Description of change
Due to lock inversion, when binding an analog axis as a button, spice
deadlocks. Fix that.

Also create a separate `unordered_map` that keeps track of device
handles so that `WM_INPUT` handle can look up devices without having to
acquire the larger `devices_mutex` which could be held by (potentially)
lengthy operations like hotplug.

Fix more synchronization issues around hotplug. Latent bug exposed by
MIDI 2.0 issues.

## Testing
This commit is contained in:
bicarus
2026-07-18 03:09:27 -07:00
committed by GitHub
parent e1d1b39567
commit c080bbe301
8 changed files with 160 additions and 78 deletions
+4 -5
View File
@@ -238,8 +238,6 @@ void rawinput::RawInputManager::devices_scan_midi() {
midi_device.name = midi_identifier;
midi_device.desc = to_string(midi_device_caps.szPname);
midi_device.info = midi_device_info;
midi_device.mutex = new std::mutex();
midi_device.mutex_out = new std::mutex();
midi_device.midiInfo = midi_device_midi_info;
// mutate the shared device list under lock (the slow WinMM calls above
@@ -256,10 +254,9 @@ void rawinput::RawInputManager::devices_scan_midi() {
// carry over ID
midi_device.id = device.id;
// destruct and replace, reusing the slot's existing mutexes
// destruct and replace the slot in place under its locks
this->devices_destruct(&device);
reuse_device_mutexes(midi_device, device);
device = midi_device;
replace_device_slot(device, midi_device);
// notify change
for (auto &cb : this->callback_change) {
@@ -275,6 +272,8 @@ void rawinput::RawInputManager::devices_scan_midi() {
}
// add device to list
midi_device.mutex = new std::mutex();
midi_device.mutex_out = new std::mutex();
auto &device = this->devices.emplace_back(midi_device);
// notify add