You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[MTRDevice] Defer first Thread subscription until operational advertisement seen
On a cold start where the Home app foregrounds before the Thread interface
has finished coming up, _delegateAdded -> _ensureSubscriptionForExistingDelegates
-> _setupSubscriptionWithReason fires the very first SubscribeRequest before
threadradiod's [WED_START] completes. The send fails immediately with
"OS Error 0x02000041: No route to host" (errno 65) from
UDPEndPointImplSockets.cpp. We then back off and retry, wasting 3-6 seconds
of coldstart on a doomed attempt.
Gate the first subscription attempt: if _deviceUsesThread is true and we have
no cached _lastSubscriptionIPAddress, defer scheduling the pool work until
either (a) nodeMayBeAdvertisingOperational fires for this device -- the strong
signal that the Thread interface is up and the accessory is reachable -- or
(b) a 1-second watchdog elapses -- the safety net for devices that never
advertise during the deferral window.
Implementation:
- New deferringFirstThreadSubscription / hasDeferredFirstThreadSubscription
properties on MTRDevice_Concrete. The first is YES only during the
deferral window; the second is a one-shot latch so subsequent re-entries
of _ensureSubscriptionForExistingDelegates (notably the one
nodeMayBeAdvertisingOperational triggers after clearing the deferral)
don't re-enter the deferral path.
- _ensureSubscriptionForExistingDelegates factors the existing pool-work
scheduling out into a local block scheduleSubscriptionPoolWork that the
deferral watchdog reuses verbatim.
- nodeMayBeAdvertisingOperational, when it observes a pending first-Thread
deferral, clears the flag and re-enters _ensureSubscriptionForExistingDelegates
with reason "operational advertisement seen" instead of going through the
normal _triggerResubscribeWithReason path (which would no-op because we
aren't yet in MTRInternalDeviceStateSubscribing).
- 1s watchdog runs on the device queue, takes _lock, double-checks the
deferral flag (the advertisement path may have cleared it racingly), and
if still set proceeds with the original scheduling.
Only Thread devices are affected; Wi-Fi/Ethernet devices retain the existing
immediate behavior. In the worst case (device that never advertises), the
first subscribe is delayed by exactly 1s vs. today's "fire immediately, fail
in 3-6s, then retry" behavior -- still a substantial coldstart win.
Adds behavior tests covering the deferral, the advertisement-clears-deferral
path, the 1s watchdog, and the invalidate-during-deferral safety path.
rdar://168903097
0 commit comments