From 2f0d0963e284184a68ccdf80f92da22a051d3e74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20NEDJAR?= Date: Tue, 28 Apr 2026 12:24:19 +0200 Subject: [PATCH] fix: flush remaining OpenOCD log lines after process exits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- src/open_ocd_task.rs | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/open_ocd_task.rs b/src/open_ocd_task.rs index e75a4fe..8739125 100644 --- a/src/open_ocd_task.rs +++ b/src/open_ocd_task.rs @@ -186,11 +186,14 @@ where let output: ExitStatus; let mut tmp_deque: VecDeque = VecDeque::new(); - loop { - if let Ok(mut deque) = mutex_messages.lock() { - tmp_deque = deque.clone(); - deque.clear(); + let drain = |tmp_deque: &mut VecDeque, mutex: &Arc>>| { + if let Ok(mut deque) = mutex.lock() { + tmp_deque.extend(deque.drain(..)); } + }; + + loop { + drain(&mut tmp_deque, &mutex_messages); while let Some(msg) = tmp_deque.pop_front() { if let Some(ref mut s) = sender { @@ -204,6 +207,20 @@ where output = status; let _ = thread_stdout.join(); let _ = thread_stderr.join(); + + // Final drain: the reader threads may have pushed lines after the + // last in-loop drain and before they finished. Without this pass, + // the very last OpenOCD output (often the diagnostic on failure) + // would be silently dropped. + drain(&mut tmp_deque, &mutex_messages); + while let Some(msg) = tmp_deque.pop_front() { + if let Some(ref mut s) = sender { + let _ = s.send(MSG::log(msg)).await; + } else { + logs.push(msg); + } + } + break; }