Skip to content

Commit 911fc92

Browse files
authored
Merge pull request uutils#9598 from sylvestre/tail-intermittent-2
tail: fix intermittent overlay-headers test by batching inotify events
2 parents 1ffad82 + adafa2f commit 911fc92

File tree

3 files changed

+61
-3
lines changed

3 files changed

+61
-3
lines changed

src/uu/tail/src/follow/watch.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -576,9 +576,17 @@ pub fn follow(mut observer: Observer, settings: &Settings) -> UResult<()> {
576576
// Drain any additional pending events to batch them together.
577577
// This prevents redundant headers when multiple inotify events
578578
// are queued (e.g., after resuming from SIGSTOP).
579-
while let Ok(Ok(event)) = observer.watcher_rx.as_mut().unwrap().receiver.try_recv()
580-
{
581-
process_event(&mut observer, event, settings, &mut paths)?;
579+
// Multiple iterations with spin_loop hints give the notify
580+
// background thread chances to deliver pending events.
581+
for _ in 0..100 {
582+
while let Ok(Ok(event)) =
583+
observer.watcher_rx.as_mut().unwrap().receiver.try_recv()
584+
{
585+
process_event(&mut observer, event, settings, &mut paths)?;
586+
}
587+
// Use both yield and spin hint for broader CPU support
588+
std::thread::yield_now();
589+
std::hint::spin_loop();
582590
}
583591
}
584592
Ok(Err(notify::Error {

util/gnu-patches/series

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ tests_tsort.patch
1111
tests_du_move_dir_while_traversing.patch
1212
test_mkdir_restorecon.patch
1313
error_msg_uniq.diff
14+
tests_tail_overlay_headers.patch
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
--- gnu.orig/tests/tail/overlay-headers.sh 2025-12-07 23:20:20.566198669 +0100
2+
+++ gnu/tests/tail/overlay-headers.sh 2025-12-07 23:20:20.570198688 +0100
3+
@@ -56,26 +56,39 @@
4+
5+
kill -0 $pid || fail=1
6+
7+
-# Wait for 5 initial lines
8+
-retry_delay_ wait4lines_ .1 6 5 || fail=1
9+
+# Wait for 5 initial lines (2 headers + 2 content lines + 1 blank)
10+
+retry_delay_ wait4lines_ .1 6 5 || { echo "Failed waiting for initial 5 lines"; fail=1; }
11+
+
12+
+echo "=== After initial wait, line count: $(countlines_) ==="
13+
+echo "=== Initial output: ===" && cat out && echo "=== End initial output ==="
14+
15+
# Suspend tail so single read() caters for multiple inotify events
16+
-kill -STOP $pid || fail=1
17+
+kill -STOP $pid || { echo "Failed to STOP tail process"; fail=1; }
18+
19+
# Interleave writes to files to generate overlapping inotify events
20+
echo line >> file1 || framework_failure_
21+
echo line >> file2 || framework_failure_
22+
echo line >> file1 || framework_failure_
23+
echo line >> file2 || framework_failure_
24+
+echo "=== Files written, resuming tail ==="
25+
26+
# Resume tail processing
27+
-kill -CONT $pid || fail=1
28+
+kill -CONT $pid || { echo "Failed to CONT tail process"; fail=1; }
29+
30+
-# Wait for 8 more lines
31+
-retry_delay_ wait4lines_ .1 6 13 || fail=1
32+
+# Wait for 8 more lines (should total 13)
33+
+retry_delay_ wait4lines_ .1 6 13 || { echo "Failed waiting for 13 total lines"; fail=1; }
34+
35+
kill $sleep && wait || framework_failure_
36+
37+
-test "$(countlines_)" = 13 || fail=1
38+
+final_count=$(countlines_)
39+
+echo "=== Final line count: $final_count (expected 13) ==="
40+
+
41+
+if test "$final_count" != 13; then
42+
+ echo "=== FAILURE: Expected 13 lines, got $final_count ==="
43+
+ echo "=== Full output content: ==="
44+
+ cat -A out
45+
+ echo "=== End output content ==="
46+
+ fail=1
47+
+fi
48+
49+
Exit $fail

0 commit comments

Comments
 (0)