Add configurable timeouts to XLinkConnect and XLinkOpenStream#104
Open
alicespetma-stack wants to merge 2 commits intoluxonis:masterfrom
Open
Add configurable timeouts to XLinkConnect and XLinkOpenStream#104alicespetma-stack wants to merge 2 commits intoluxonis:masterfrom
alicespetma-stack wants to merge 2 commits intoluxonis:masterfrom
Conversation
XLinkConnect() and XLinkOpenStream() previously passed XLINK_NO_RW_TIMEOUT to DispatcherWaitEventComplete(), causing a bare sem_wait() that blocks forever if the remote device fails to respond after firmware boot. This adds: - XLinkConnectWithTimeout(handler, timeoutMs) - XLinkOpenStreamWithTimeout(id, name, size, timeoutMs) - XLINK_CONNECT_TIMEOUT (5s) and XLINK_OPEN_STREAM_TIMEOUT (5s) defaults The existing XLinkConnect() and XLinkOpenStream() now delegate to the WithTimeout variants using these defaults, matching the pattern established by XLinkWriteDataWithTimeout/XLinkReadDataWithTimeout. If the device is responsive, PING and stream creation complete in <100ms. The 5s default is generous but prevents indefinite hangs when the device firmware fails to initialize its XLink dispatcher after boot. Callers can pass XLINK_NO_RW_TIMEOUT to the WithTimeout variants to restore the previous infinite-wait behavior if needed.
The previous timeout implementation in DispatcherWaitEventComplete counted loop iterations (each with a 1ms usleep) to approximate the timeout duration. This was inaccurate because usleep(1000) can sleep 1-10ms depending on system load and scheduler granularity, making a "5000ms" timeout anywhere from 5s to 50s in practice. Replace with getMonotonicTimestamp() (backed by std::chrono::steady_clock) to measure actual elapsed time. This: - Gives accurate timeouts regardless of system load - Remains immune to NTP/system clock jumps (the original reason sem_timedwait was replaced with the polling loop) - Works cross-platform (steady_clock on Windows, CLOCK_MONOTONIC on Linux) Resolves the TODO comment: "This is a temporary solution. TODO: replace this with something more efficient." Related: luxonis#86
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
XLinkConnect()andXLinkOpenStream()passXLINK_NO_RW_TIMEOUTtoDispatcherWaitEventComplete(), which results in a baresem_wait()that blocks the calling thread indefinitely if the remote device fails to respond after firmware boot. This is the same pattern that PR #5 addressed for data read/write operations, but the connect and stream-open paths were not covered.Additionally, the timeout path in
DispatcherWaitEventCompleteused iteration counting (while (timeoutMs--)withusleep(1000)) to approximate timeout duration. This was inaccurate becauseusleep(1000)can sleep 1-10ms depending on system load, making a "5000ms" timeout anywhere from 5s to 50s in practice.Changes
Commit 1: Add configurable timeouts to XLinkConnect and XLinkOpenStream
XLinkConnectWithTimeout(handler, timeoutMs)— connect with configurable ping timeoutXLinkOpenStreamWithTimeout(id, name, size, timeoutMs)— open stream with configurable timeoutXLINK_CONNECT_TIMEOUT(5s) andXLINK_OPEN_STREAM_TIMEOUT(5s) default constantsXLinkConnect()andXLinkOpenStream()now delegate to theWithTimeoutvariants using these defaultsCommit 2: Replace iteration-counting timeout with monotonic clock measurement
Replaces the
while (timeoutMs--)polling loop withgetMonotonicTimestamp()(backed bystd::chrono::steady_clock, already in the codebase viaXLinkTime.h). This:sem_timedwaitwas replaced)Motivation
When a device firmware fails to initialize its XLink dispatcher after boot (e.g. due to a firmware hang or hardware instability), the host-side
XLinkConnect()PING handshake blocks forever inDispatcherWaitEventComplete(). Since watchdog threads in depthai-core are created afterXLinkConnectandXLinkOpenStreamcomplete, there is no recovery mechanism — the calling thread is permanently stuck.With this change, these operations time out after 5 seconds by default. For a responsive device, PING and stream creation complete in well under 100ms, so the 5s default has no impact on normal operation. Callers can pass
XLINK_NO_RW_TIMEOUTto theWithTimeoutvariants to restore the previous infinite-wait behavior if needed.Files Modified
include/XLink/XLinkPublicDefines.hXLINK_CONNECT_TIMEOUTandXLINK_OPEN_STREAM_TIMEOUTconstantsinclude/XLink/XLink.hXLinkConnectWithTimeout()andXLinkOpenStreamWithTimeout()src/shared/XLinkDevice.cXLinkConnectWithTimeout(),XLinkConnect()delegates to itsrc/shared/XLinkData.cXLinkOpenStreamWithTimeout(),XLinkOpenStream()delegates to itsrc/shared/XLinkDispatcher.cBackward Compatibility
XLinkConnect()andXLinkOpenStream()require no changesWithTimeoutAPI follows the same pattern as the existingXLinkWriteDataWithTimeout/XLinkReadDataWithTimeout/XLinkReadMoveDataWithTimeoutTest Plan
XLinkConnectreturnsX_LINK_TIMEOUTafter 5s instead of hangingXLinkConnection::initDevice()can now retry on timeout