Add hid_set_num_input_buffers() API#787
Conversation
Exposes a new public function to resize the per-device input report queue. High-throughput HID devices (medical telemetry, high-poll-rate gaming peripherals, data acquisition hardware) emit bursts of input reports that exceed the current hardcoded queue sizes (30 on macOS and the libusb backend, 64 on Windows). When a burst exceeds the queue, reports are silently dropped with no error indication to the caller. This adds: - hid_set_input_report_buffer_size(dev, size) in hidapi.h - HID_API_MAX_INPUT_REPORT_BUFFER_SIZE (1024) cap to prevent unbounded memory growth Per-backend behavior: - macOS: resizes the userspace IOHIDQueue-fed report queue - Linux libusb: resizes the userspace report queue - Windows: wraps HidD_SetNumInputBuffers (parity with existing behavior) - Linux hidraw: no-op (kernel manages buffering) - NetBSD: no-op (kernel manages buffering) Defaults are unchanged, so existing callers are unaffected. Values outside [1, HID_API_MAX_INPUT_REPORT_BUFFER_SIZE] are rejected with -1. Thread-safe on macOS (dev->mutex) and libusb (dev->thread_state), matching the locks used by the respective report callbacks. Addresses the same need as closed issue libusb#154 (HidD_SetNumInputBuffers exposure) and complements libusb#725 (callback-based input API).
Youw
left a comment
There was a problem hiding this comment.
refer to comments, otherwise looks good
Per maintainer feedback on PR libusb#787: - Remove if (!dev) validation from all 5 backends. hidapi convention is that device functions trust the caller to pass a valid handle; only hid_close is permitted to accept NULL. - Reword the inline comment in linux/hid.c and netbsd/hid.c to lead with "No-op" so the caller-visible behavior is explicit at the implementation site.
|
Thanks for reviewing. I have made the changes. |
|
I think the name of the Win32-API |
… controls the number of input report buffers, not their byte size. - Function: hid_set_input_report_buffer_size -> hid_set_num_input_buffers - Macro: HID_API_MAX_INPUT_REPORT_BUFFER_SIZE -> HID_API_MAX_NUM_INPUT_BUFFERS - Parameter: buffer_size -> num_buffers - Error string: "buffer_size out of range" -> "num_buffers out of range"
|
Good callout @JoergAtGithub. Have renamed the function to @Youw - Please let me know if any further changes required. Thanks both. |
|
@auxcorelabs If not, do you have a simple test to share? Thanks. |
| /* No-op on Linux hidraw and BSD backends: the kernel manages input | ||
| report buffering and there is no userspace queue to resize. The | ||
| call is accepted (returns 0) to preserve a consistent cross-platform | ||
| API so callers do not need per-backend conditional code. */ |
There was a problem hiding this comment.
I meant having this section in the .h as a NOTE section.
not much point having it here as verbose versino, specifically no point mentioning other backends from within (like mentioning BSD backend inside of the hidraw implementation)
…ile commentary, add hidtest coverage - hidapi/hidapi.h: replace the Defaults per backend list with an @note Per-backend behavior block covering macOS / Windows / libusb / hidraw / uhid semantics, ranges, and defaults. Per @Youw, the public header is the canonical place for the cross-backend contract. - linux/hid.c, netbsd/hid.c: drop the comment that cross-referenced other backends. The (void)num_buffers; idiom and the header contract speak for themselves. - libusb/hid.c: drop the self-scoped no-error-registration note for the same reason. - hidtest/test.c: add a compile-time symbol reference and a runtime call hid_set_num_input_buffers(handle, 500) right after hid_open() succeeds, per @mcuee. Both guarded on HID_API_VERSION >= 0.16.0 so they activate in the 0.16 release cycle, matching the precedent of hid_send_output_report at 0.15.0.
Exposes a new public function
hid_set_input_report_buffer_size(dev, size)to resize the per-device input report queue.High-throughput HID devices (medical telemetry, high-poll-rate gaming peripherals, data acquisition hardware) can emit bursts of input reports that exceed the current hardcoded queue sizes (30 on macOS and Linux/libusb, 64 on Windows). When a burst exceeds the queue, reports are silently dropped with no error indication to the caller. Observed on hardware emitting ~90 reports in 200 ms bursts: both the macOS and Linux/libusb backends silently drop ~20% of frames.
Per-backend behavior
HidD_SetNumInputBuffers(parity with existing behavior)Safety
[1, HID_API_MAX_INPUT_REPORT_BUFFER_SIZE]return -1; NULL dev returns -1 with a global errordev->mutex/dev->thread_state) as the respective report callbackDesign notes
hid_deviceis opaque inhidapi.h, so struct field additions in backend-private files are not an ABI break.INT_MAX(malicious or buggy). We've measured bursts up to ~90 reports deep in practice; 1024 leaves room for devices ~10× more demanding. Overridable via-DHID_API_MAX_INPUT_REPORT_BUFFER_SIZE=Nat build time for memory-constrained targets.hid_get_input_report()instead? That API issues a host-initiatedGET_REPORTrequest (via the control endpoint or OS equivalent). It does not drain the interrupt-endpoint queue that streaming devices fill, and in practice many devices either don't implementGET_REPORTfor input reports or respond incorrectly. The two APIs use different USB transfer mechanisms (interrupt endpoint vs. control endpoint); this PR fixes the interrupt-streaming path.References
HidD_SetNumInputBuffersfunctionality to callersCI equivalent status
All upstream CI equivalents tested locally:
-Wall -Wextra -pedantic -Werror -Wformat-signednessHIDAPI_ENABLE_ASAN=ON-Wall -Wextra -pedantic -Werror/W4 /WXZero warnings on all platforms. Symbol verified exported in all built artifacts.