os: fix race between file I/O and Close

Now that the os package uses internal/poll on Unix and Windows systems,
it can rely on internal/poll reference counting to ensure that the
file descriptor is not closed until all I/O is complete.

That was already working. This CL completes the job by not trying to
modify the Sysfd field when it might still be used by the I/O routines.

Fixes #7970

Change-Id: I7a3daa1a6b07b7345bdce6f0cd7164bd4eaee952
Reviewed-on: https://go-review.googlesource.com/41674
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Ian Lance Taylor 2017-04-24 21:49:26 -07:00
parent 9459c03b29
commit 11c7b4491b
9 changed files with 46 additions and 17 deletions

View file

@ -183,14 +183,13 @@ func (f *File) Close() error {
}
func (file *file) close() error {
if file == nil || file.pfd.Sysfd == badFd {
if file == nil {
return syscall.EINVAL
}
var err error
if e := file.pfd.Close(); e != nil {
err = &PathError{"close", file.name, e}
}
file.pfd.Sysfd = badFd // so it can't be closed again
// no need for a finalizer anymore
runtime.SetFinalizer(file, nil)