mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 14:50:41 -07:00
c080bbe301
## 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
32 lines
1.1 KiB
C++
32 lines
1.1 KiB
C++
#include "rawinput_handles.h"
|
|
|
|
void rawinput::RawInputHandles::add(Device *device) {
|
|
std::lock_guard<std::mutex> lock(this->mutex);
|
|
this->devices[device->handle] = device;
|
|
}
|
|
|
|
void rawinput::RawInputHandles::remove(Device *device) {
|
|
std::lock_guard<std::mutex> lock(this->mutex);
|
|
|
|
// teardown is shared by every device type, and handles can be reused; only erase
|
|
// an entry that still belongs to this exact RawInput device
|
|
auto it = this->devices.find(device->handle);
|
|
if (it != this->devices.end() && it->second == device) {
|
|
this->devices.erase(it);
|
|
}
|
|
}
|
|
|
|
rawinput::RawInputHandles::AcquiredDevice rawinput::RawInputHandles::acquire(HANDLE handle) {
|
|
std::lock_guard<std::mutex> index_lock(this->mutex);
|
|
auto it = this->devices.find(handle);
|
|
if (it == this->devices.end()) {
|
|
return {};
|
|
}
|
|
|
|
auto *device = it->second;
|
|
|
|
// take the device mutex while index_lock is still held so teardown can't free it
|
|
// between the lookup and the lock
|
|
return {device, std::unique_lock<std::mutex>(*device->mutex)};
|
|
}
|