Skip to content

Fix data race in GamepadManager::updateAll() with hotplug thread#1

Merged
Union-Crax merged 1 commit into
mainfrom
claude/blissful-cannon-7r6Ow
Jun 1, 2026
Merged

Fix data race in GamepadManager::updateAll() with hotplug thread#1
Union-Crax merged 1 commit into
mainfrom
claude/blissful-cannon-7r6Ow

Conversation

@Union-Crax

Copy link
Copy Markdown
Contributor

Summary

Fixed a critical data race condition in GamepadManager::updateAll() that could cause use-after-free crashes when gamepads disconnect during frame updates.

Key Changes

  • Added mutex locking in updateAll() to synchronize access to the gamepads_ collection with the hotplug thread
  • The hotplug thread's check_for_disconnected_devices() can destroy gamepad devices while the polling thread iterates and dereferences them, causing a race condition
  • Implemented std::lock_guard<std::timed_mutex> to protect the gamepad iteration
  • Simplified the gamepad state update logic by removing unnecessary conditional check around updateState()

Implementation Details

  • The hotplug thread already uses try_lock_for() and gracefully skips cycles when the lock is unavailable, preventing potential deadlocks during game launch
  • This synchronization strategy ensures the polling thread can safely iterate and dereference gamepad devices without interference from concurrent device destruction
  • The fix addresses crashes that occurred whenever a gamepad disconnected mid-frame

https://claude.ai/code/session_01Rht2wE4RuR9k63DGF1eUKW

…ect crash

GamepadManagerImpl::updateAll() iterated gamepads_ and dereferenced each
device every frame without holding mutex_, while the hotplug thread could
simultaneously destroy a device (gamepads_[i].reset()) in
check_for_disconnected_devices(). That data race / use-after-free crashed
the host whenever a controller dropped mid-frame.

Take the same timed_mutex every other accessor uses. The hotplug thread
already uses try_lock_for and skips a cycle when it can't acquire the lock,
so this cannot deadlock game launch. Also dropped the empty dead if-block
around updateState().
@Union-Crax Union-Crax merged commit cd06f33 into main Jun 1, 2026
5 checks passed
@Union-Crax Union-Crax deleted the claude/blissful-cannon-7r6Ow branch June 1, 2026 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants