mirror of
https://github.com/golang/go
synced 2024-11-19 11:34:49 -07:00
os: don't wait for Close if the File was returned by NewFile
os.NewFile doesn't put the fd into non-blocking mode. In most cases, an *os.File returned by os.NewFile is in blocking mode. Updates #7970 Updates #21856 Updates #23111 Change-Id: Iab08432e41f7ac1b5e25aaa8855d478adb7f98ed Reviewed-on: https://go-review.googlesource.com/83995 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
b944f91f15
commit
e28a0d397b
@ -56,6 +56,7 @@ func (fd *FD) Init(net string, pollable bool) error {
|
||||
fd.isFile = true
|
||||
}
|
||||
if !pollable {
|
||||
fd.isBlocking = true
|
||||
return nil
|
||||
}
|
||||
return fd.pd.init(fd)
|
||||
|
@ -10,6 +10,7 @@ package os_test
|
||||
import (
|
||||
"fmt"
|
||||
"internal/testenv"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
osexec "os/exec"
|
||||
@ -222,12 +223,28 @@ func TestReadNonblockingFd(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Test that we don't let a blocking read prevent a close.
|
||||
func TestCloseWithBlockingRead(t *testing.T) {
|
||||
func TestCloseWithBlockingReadByNewFile(t *testing.T) {
|
||||
var p [2]int
|
||||
err := syscall.Pipe(p[:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// os.NewFile returns a blocking mode file.
|
||||
testCloseWithBlockingRead(t, os.NewFile(uintptr(p[0]), "reader"), os.NewFile(uintptr(p[1]), "writer"))
|
||||
}
|
||||
|
||||
func TestCloseWithBlockingReadByFd(t *testing.T) {
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Calling Fd will put the file into blocking mode.
|
||||
_ = r.Fd()
|
||||
testCloseWithBlockingRead(t, r, w)
|
||||
}
|
||||
|
||||
// Test that we don't let a blocking read prevent a close.
|
||||
func testCloseWithBlockingRead(t *testing.T, r, w *os.File) {
|
||||
defer r.Close()
|
||||
defer w.Close()
|
||||
|
||||
@ -248,18 +265,18 @@ func TestCloseWithBlockingRead(t *testing.T) {
|
||||
close(c)
|
||||
}(c1)
|
||||
|
||||
// Calling Fd will put the file into blocking mode.
|
||||
_ = r.Fd()
|
||||
|
||||
wg.Add(1)
|
||||
go func(c chan bool) {
|
||||
defer wg.Done()
|
||||
var b [1]byte
|
||||
_, err = r.Read(b[:])
|
||||
_, err := r.Read(b[:])
|
||||
close(c)
|
||||
if err == nil {
|
||||
t.Error("I/O on closed pipe unexpectedly succeeded")
|
||||
}
|
||||
if err != io.EOF {
|
||||
t.Errorf("got %v, expected io.EOF", err)
|
||||
}
|
||||
}(c2)
|
||||
|
||||
for c1 != nil || c2 != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user