mirror of
https://github.com/golang/go
synced 2024-11-23 00:10:07 -07:00
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 <iant@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Trust: Emmanuel Odeke <emmanuel@orijtech.com>
This commit is contained in:
parent
52bf14e0e8
commit
6382ec1aba
@ -6,6 +6,7 @@ package poll_test
|
||||
|
||||
import (
|
||||
"internal/poll"
|
||||
"internal/syscall/unix"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"testing"
|
||||
@ -16,8 +17,8 @@ import (
|
||||
func checkPipes(fds []int) bool {
|
||||
for _, fd := range fds {
|
||||
// Check if each pipe fd has been closed.
|
||||
err := syscall.FcntlFlock(uintptr(fd), syscall.F_GETFD, nil)
|
||||
if err == nil {
|
||||
_, _, errno := syscall.Syscall(unix.FcntlSyscall, uintptr(fd), syscall.F_GETPIPE_SZ, 0)
|
||||
if errno == 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -37,8 +38,8 @@ func TestSplicePipePool(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Skip("failed to create pipe, skip this test")
|
||||
}
|
||||
prfd, pwfd := poll.GetPipeFds(p)
|
||||
fds = append(fds, prfd, pwfd)
|
||||
_, pwfd := poll.GetPipeFds(p)
|
||||
fds = append(fds, pwfd)
|
||||
ps = append(ps, p)
|
||||
}
|
||||
for _, p = range ps {
|
||||
@ -46,19 +47,28 @@ func TestSplicePipePool(t *testing.T) {
|
||||
}
|
||||
ps = nil
|
||||
|
||||
var ok bool
|
||||
// Trigger garbage collection to free the pipes in sync.Pool and check whether or not
|
||||
// those pipe buffers have been closed as we expected.
|
||||
for i := 0; i < 5; i++ {
|
||||
// Exploit the timeout of "go test" as a timer for the subsequent verification.
|
||||
timeout := 5 * time.Minute
|
||||
if deadline, ok := t.Deadline(); ok {
|
||||
timeout = deadline.Sub(time.Now())
|
||||
timeout -= timeout / 10 // Leave 10% headroom for cleanup.
|
||||
}
|
||||
expiredTime := time.NewTimer(timeout)
|
||||
defer expiredTime.Stop()
|
||||
|
||||
// Trigger garbage collection repeatedly, waiting for all pipes in sync.Pool
|
||||
// to either be deallocated and closed, or to time out.
|
||||
for {
|
||||
runtime.GC()
|
||||
time.Sleep(time.Duration(i*100+10) * time.Millisecond)
|
||||
if ok = checkPipes(fds); ok {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
if checkPipes(fds) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !ok {
|
||||
select {
|
||||
case <-expiredTime.C:
|
||||
t.Fatal("at least one pipe is still open")
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user