Skip to content

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

Open
m-va wants to merge 1 commit into
collabora:masterfrom
m-va:fix-hidapi-close-hang
Open

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

Conversation

@m-va

@m-va m-va commented Aug 18, 2026

Copy link
Copy Markdown

(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
#ifndef HIDAPI
    libusb_handle_events(sv->usbctx);
#endif
    for (int i = 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

@bl4ckb0ne bl4ckb0ne 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 thread src/driver_vive.hidapi.h Outdated
@m-va
m-va force-pushed the fix-hidapi-close-hang branch from 76304f8 to 83b5a42 Compare August 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.

Fixes collabora#312

Assisted-by: Claude:claude-opus-5
@m-va
m-va force-pushed the fix-hidapi-close-hang branch from 83b5a42 to 8e83802 Compare August 24, 2026 23:00
Sign up for free to 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