Skip to content

fix: flush remaining OpenOCD log lines after process exits#14

Merged
nedseb merged 1 commit into
mainfrom
fix/openocd-final-drain
Apr 28, 2026
Merged

fix: flush remaining OpenOCD log lines after process exits#14
nedseb merged 1 commit into
mainfrom
fix/openocd-final-drain

Conversation

@nedseb
Copy link
Copy Markdown
Contributor

@nedseb nedseb commented Apr 28, 2026

Summary

Closes #9.

run_command_sender polls the OpenOCD child process and drains queued log lines into the in-app sender. Between the last in-loop drain and the moment try_wait() returns Some(...), the reader threads can still push lines into the mutex. After joining the threads (which guarantees they're done writing) the loop broke out without one last drain — those final messages stayed in the mutex and were silently dropped from the UI.

That's exactly when OpenOCD emits the diagnostic that explains why a flash failed (** Error: target halted unexpectedly, ** verification failed**, transport errors, etc.). Users were seeing a generic Exit code: 1 with no context.

This PR extracts the drain into a tiny closure shared by the polling loop and a new post-exit pass, run after the reader threads are joined and before break. No behavior change in the success path.

Test plan

  • Trigger a deliberate failure (wrong target, missing probe) and confirm the OpenOCD failure message now appears in the log widget instead of disappearing.
  • Successful flash flow still streams logs progressively and ends cleanly without duplicates.
  • No CPU regression — the polling loop's 50 ms Timer::after is unchanged.

run_command_sender's drain-and-poll loop forwarded mutex contents to
the sender, then checked try_wait() — if the child had exited it
joined the reader threads and broke out without one last drain.

Race: between the last lock/clear and the moment try_wait() returns
Some(...), the reader threads can still push lines. Joining the
threads guarantees they're done pushing, but those last messages stay
in the mutex and are never forwarded. This is exactly when OpenOCD
emits the diagnostic line that explains why a flash failed — and it
was disappearing from the in-app log.

Add a final drain after `thread_stdout.join()` / `thread_stderr.join()`
and before `break`. Extracted the drain into a small closure so the
loop body and the post-exit pass share the same logic.

Closes #9.
Copilot AI review requested due to automatic review settings April 28, 2026 10:24
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Ensures the UI receives the final OpenOCD log lines emitted right before process termination by performing one last post-exit drain after the stdout/stderr reader threads have been joined.

Changes:

  • Refactors the message-queue drain logic into a small reusable closure.
  • Adds a final drain-and-forward pass after try_wait() reports exit and the reader threads are joined, preventing last-moment log loss.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@nedseb nedseb merged commit 86cb676 into main Apr 28, 2026
7 checks passed
@nedseb nedseb deleted the fix/openocd-final-drain branch April 28, 2026 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Last OpenOCD log lines can be dropped: missing final drain after child exit

2 participants