Skip to content

Fixed standalone locking bugs in HID host idle get/set#264

Merged
fdesbiens merged 1 commit into
devfrom
fix-hid-standalone-idle-locking
Jun 4, 2026
Merged

Fixed standalone locking bugs in HID host idle get/set#264
fdesbiens merged 1 commit into
devfrom
fix-hid-standalone-idle-locking

Conversation

@fdesbiens
Copy link
Copy Markdown
Contributor

Summary

Two bugs discovered while reviewing and fixing thread-safety issues in the new ux_host_class_hid_protocol_get/set functions (PR #244).

Changes

1. idle_get.c: wrong operator acquires no lock in standalone mode

Line 104 used &= ~UX_HOST_CLASS_HID_FLAG_LOCK (the release/clear operation) instead of |= UX_HOST_CLASS_HID_FLAG_LOCK (acquire/set). The preceding check correctly returns UX_BUSY when the flag is set, but the follow-on line then immediately clears it instead of setting it. The net effect is that the HID instance is never actually locked in UX_HOST_STANDALONE mode, making the mutual-exclusion check a no-op and leaving idle_get unprotected against concurrent calls.

2. idle_set.c: standalone path used a blocking spin-loop

The standalone branch called _ux_host_class_hid_idle_set_run() in a do/while loop, blocking the caller until the transfer completed. This is inconsistent with every other inline HID control-transfer function (idle_get, report_get, report_set, protocol_get, protocol_set) which all use the direct UX_DISABLE/UX_RESTORE atomic flag pattern and return UX_BUSY if the instance or device endpoint is already locked.

Replaced with the same inline standalone locking pattern used by the other functions: atomic HID_FLAG_LOCK acquire, atomic DEVICE_FLAG_LOCK acquire with AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET, and an AUTO_WAIT check at completion consistent with idle_get behavior.

Two issues discovered while reviewing and fixing thread-safety issues in
the new ux_host_class_hid_protocol_get/set functions (PR #244).

1. idle_get.c: wrong operator acquires no lock in standalone mode

   Line 104 used '&= ~UX_HOST_CLASS_HID_FLAG_LOCK' (the release/clear
   operation) instead of '|= UX_HOST_CLASS_HID_FLAG_LOCK' (acquire/set).
   The preceding check correctly returns UX_BUSY when the flag is set,
   but the follow-on line then immediately clears it instead of setting it.
   The net effect is that the HID instance is never actually locked in
   UX_HOST_STANDALONE mode, making the mutual-exclusion check a no-op.

2. idle_set.c: standalone path used a blocking spin-loop

   The standalone branch called _ux_host_class_hid_idle_set_run() in a
   do/while loop, blocking the caller until the transfer completed. This
   is inconsistent with every other inline HID control-transfer function
   (idle_get, report_get, report_set, protocol_get, protocol_set) which
   all use the direct UX_DISABLE/UX_RESTORE atomic flag pattern and
   return UX_BUSY if the instance or device endpoint is already locked.

   Replaced with the same inline standalone locking pattern used by the
   other functions: atomic HID FLAG_LOCK acquire, atomic DEVICE_FLAG_LOCK
   acquire with AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET, and an
   AUTO_WAIT check at completion consistent with idle_get behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens fdesbiens changed the title Fix standalone locking bugs in HID host idle get/set Fixed standalone locking bugs in HID host idle get/set Jun 4, 2026
@fdesbiens fdesbiens merged commit 94cdd1e into dev Jun 4, 2026
1 check passed
@fdesbiens fdesbiens deleted the fix-hid-standalone-idle-locking branch June 4, 2026 19:45
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.

1 participant