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
{{ message }}
Repository navigation
ESP32 native espflash timeout leaks the serial port to the esptool fallback (EBUSY) #1614
When the native espflash verify (or write) hits its wall-clock timeout, Esp32Deployer returns immediately and the caller falls back to esptool, but the timed-out spawn_blocking thread still owns the serial port. The esptool fallback then fails with EBUSY, and the port stays held for tens of seconds after the deploy has already failed.
The code comments claim the opposite:
On timeout the blocking task is detached (the Flasher drops, closing the serial port)
tokio::time::timeout only drops the JoinHandle. A spawn_blocking closure cannot be cancelled: it runs until espflash returns on its own, and the Flasher (and its port fd) lives that whole time.
Evidence (fbuild 2.5.30, Linux, ESP32-C6 on USB-Serial-JTAG 303a:1001)
Daemon log from fbuild deploy -e esp32c6 -p /dev/ttyACM1:
18:04:01 verifying firmware.bin on /dev/ttyACM1 via espflash (esp32c6)
18:04:31 WARN native verify-flash failed (deploy failed: native verify timed out after 30s on /dev/ttyACM1); falling back to esptool
18:04:31 WARN verify-flash pre-check failed (... esptool verify-flash failed (exit 2): ERROR: Could not open /dev/ttyACM1, the port is busy or doesn't exist.
18:04:31 flashing ... via esptool (esp32c6)
-> [Errno 16] could not open port /dev/ttyACM1: Device or resource busy
Sampling /proc/*/fd every 0.5 s during a repro:
11:14:24 fbuild-daemon holds ttyACM1 (native verify starts)
11:14:43 deploy fails: esptool EBUSY (≈30 s timeout fired, fallback ran)
11:15:23 holder released (≈40 s after the timeout)
No other process held the port. The deploy fails deterministically whenever native verify times out, and the user-visible error ("port is busy") points at the wrong cause.
This is a concrete root cause for at least part of #1429 ("Release was observed within ~5 s in one instance and not at all in others").
Fix
Add one helper for port-owning blocking work: run the closure under the wall-clock budget, and on timeout keep awaiting the JoinHandle for a bounded release grace so the port is released before the caller falls back. If the grace also expires, return an error that names the still-held port instead of letting esptool fail with a misleading EBUSY. Route all three sites through it and correct the comments.
Activity