Skip to content

driver_vive: fix infinite loop when closing HIDAPI devices - #370

Merged
bl4ckb0ne merged 1 commit into
collabora:masterfrom
m-va:fix-hidapi-close-hang
Aug 27, 2026
Merged

driver_vive: fix infinite loop when closing HIDAPI devices#370
bl4ckb0ne merged 1 commit into
collabora:masterfrom
m-va:fix-hidapi-close-hang

Conversation

@m-va

@m-vam-va commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

(Re-opening #369, which was closed by accident when I deleted my fork.)

Fixes#312.

Problem

On Windows, USE_HIDAPI defaults to ON, and survive_vive_close() never
returns:

while (sv->udev_cnt) { // never reaches 0#ifndefHIDAPIlibusb_handle_events(sv->usbctx);
#endiffor (inti=0; i<sv->udev_cnt; i++) {
if (survive_handle_close_request_flag(sv->udev[i])) i--;
}
}

survive_handle_close_request_flag() only acts when usbInfo->request_close
is set. In the HIDAPI backend that flag is raised only in HAPIReceiver() when
hid_read() returns a negative value; survive_close_usb_device() closes the
HID handles without setting it. The libusb backend is unaffected because
libusb_handle_events() drives the completion callbacks that raise the flag,
and that call is #ifndef HIDAPI.

Besides hanging the process, this also means config_save() (which runs later
inside survive_close()) is never reached, so lighthouse calibration is never
written to config.json and has to be redone on every launch.

Fix

Raise the flag (and mark the interfaces shut down, mirroring the libusb path)
when the device is actually closed. Freeing the handle there is safe because
survive_usb_handle_close() is a no-op in this backend.

Testing

Windows 11 x64, MSVC, master, USE_HIDAPI=ON, two Vive Trackers (2018) over
USB with SteamVR 2.0 base stations:

  • before: survive_simple_close() did not return after 60 s; config.json
    never contained lighthouse0/lighthouse1
  • after: it returns immediately, and config.json gets the lighthouse entries,
    so a second launch starts tracking without recalibrating

@bl4ckb0nebl4ckb0ne left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You also need to disclose the gen AI usage in the commit with a Assisted-by tag (See 1)

Comment threadsrc/driver_vive.hidapi.h Outdated
@m-va
m-vaforce-pushed the fix-hidapi-close-hang branch from 76304f8 to 83b5a42CompareAugust 24, 2026 22:42
survive_vive_close() waits for every device to raise request_close, but the
HIDAPI backend only ever sets that flag from HAPIReceiver() when hid_read()
fails. survive_close_usb_device() closes the HID handles without setting it,
so the wait loop never terminates.
The libusb backend does not hit this because libusb_handle_events() drives the
transfer-completion callbacks that raise the flag, and that call is compiled
out under HIDAPI.
Set the flag when the device is closed. This also lets survive_close() reach
config_save(), so lighthouse calibration is persisted again instead of being
lost on every run.
Tested on Windows 11 x64 (MSVC, USE_HIDAPI=ON) with two Vive Trackers (2018)
over USB and SteamVR 2.0 base stations: survive_simple_close() goes from never
returning to completing immediately, and config.json gets its lighthouse0/1
entries so calibration survives a restart.
Fixescollabora#312
Assisted-by: Claude:claude-opus-5
@m-va
m-vaforce-pushed the fix-hidapi-close-hang branch from 83b5a42 to 8e83802CompareAugust 24, 2026 23:00

@bl4ckb0nebl4ckb0ne left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks :)

@bl4ckb0ne
bl4ckb0ne merged commit f1e6edd into collabora:masterAug 27, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Infinite loop when shutting down vive driver

2 participants

@m-va@bl4ckb0ne