Skip to content

Commit 6382ec1

Browse files
panjf2000odeke-em
authored andcommitted
internal/poll: fix the intermittent build failures with pipe pool
Correlative CL 308089 Fixes #45059 Change-Id: I1ff9fbf64e6620d651f287ba2a28d40f964d78a3 Reviewed-on: https://go-review.googlesource.com/c/go/+/308329 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Trust: Emmanuel Odeke <[email protected]>
1 parent 52bf14e commit 6382ec1

File tree

1 file changed

+24
-14
lines changed

1 file changed

+24
-14
lines changed

src/internal/poll/splice_linux_test.go

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package poll_test
66

77
import (
88
"internal/poll"
9+
"internal/syscall/unix"
910
"runtime"
1011
"syscall"
1112
"testing"
@@ -16,8 +17,8 @@ import (
1617
func checkPipes(fds []int) bool {
1718
for _, fd := range fds {
1819
// Check if each pipe fd has been closed.
19-
err := syscall.FcntlFlock(uintptr(fd), syscall.F_GETFD, nil)
20-
if err == nil {
20+
_, _, errno := syscall.Syscall(unix.FcntlSyscall, uintptr(fd), syscall.F_GETPIPE_SZ, 0)
21+
if errno == 0 {
2122
return false
2223
}
2324
}
@@ -37,28 +38,37 @@ func TestSplicePipePool(t *testing.T) {
3738
if err != nil {
3839
t.Skip("failed to create pipe, skip this test")
3940
}
40-
prfd, pwfd := poll.GetPipeFds(p)
41-
fds = append(fds, prfd, pwfd)
41+
_, pwfd := poll.GetPipeFds(p)
42+
fds = append(fds, pwfd)
4243
ps = append(ps, p)
4344
}
4445
for _, p = range ps {
4546
poll.PutPipe(p)
4647
}
4748
ps = nil
4849

49-
var ok bool
50-
// Trigger garbage collection to free the pipes in sync.Pool and check whether or not
51-
// those pipe buffers have been closed as we expected.
52-
for i := 0; i < 5; i++ {
50+
// Exploit the timeout of "go test" as a timer for the subsequent verification.
51+
timeout := 5 * time.Minute
52+
if deadline, ok := t.Deadline(); ok {
53+
timeout = deadline.Sub(time.Now())
54+
timeout -= timeout / 10 // Leave 10% headroom for cleanup.
55+
}
56+
expiredTime := time.NewTimer(timeout)
57+
defer expiredTime.Stop()
58+
59+
// Trigger garbage collection repeatedly, waiting for all pipes in sync.Pool
60+
// to either be deallocated and closed, or to time out.
61+
for {
5362
runtime.GC()
54-
time.Sleep(time.Duration(i*100+10) * time.Millisecond)
55-
if ok = checkPipes(fds); ok {
63+
time.Sleep(10 * time.Millisecond)
64+
if checkPipes(fds) {
5665
break
5766
}
58-
}
59-
60-
if !ok {
61-
t.Fatal("at least one pipe is still open")
67+
select {
68+
case <-expiredTime.C:
69+
t.Fatal("at least one pipe is still open")
70+
default:
71+
}
6272
}
6373
}
6474

0 commit comments

Comments
 (0)