mirror of
https://github.com/golang/go
synced 2024-11-19 00:54:42 -07:00
873dca4c17
The net package sets a finalizer on *netFD. I looked through all the uses of *netFD in the package, looking for each case where a *netFD was passed as an argument and the final reference to the argument was not a function or method call. I added a call to runtime.KeepAlive after each such final reference (there were only three). The code is safe today without the KeepAlive calls because the compiler keeps arguments alive for the duration of the function. However, that is not a language requirement, so adding the KeepAlive calls ensures that this code remains safe even if the compiler changes in the future. Change-Id: I4e2bd7c5a946035dc509ccefb4828f72335a9ee3 Reviewed-on: https://go-review.googlesource.com/27650 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
90 lines
1.7 KiB
Go
90 lines
1.7 KiB
Go
// Copyright 2013 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package net
|
|
|
|
import (
|
|
"runtime"
|
|
"syscall"
|
|
"time"
|
|
)
|
|
|
|
type pollDesc struct {
|
|
fd *netFD
|
|
closing bool
|
|
}
|
|
|
|
func (pd *pollDesc) init(fd *netFD) error { pd.fd = fd; return nil }
|
|
|
|
func (pd *pollDesc) close() {}
|
|
|
|
func (pd *pollDesc) evict() {
|
|
pd.closing = true
|
|
if pd.fd != nil {
|
|
syscall.StopIO(pd.fd.sysfd)
|
|
runtime.KeepAlive(pd.fd)
|
|
}
|
|
}
|
|
|
|
func (pd *pollDesc) prepare(mode int) error {
|
|
if pd.closing {
|
|
return errClosing
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (pd *pollDesc) prepareRead() error { return pd.prepare('r') }
|
|
|
|
func (pd *pollDesc) prepareWrite() error { return pd.prepare('w') }
|
|
|
|
func (pd *pollDesc) wait(mode int) error {
|
|
if pd.closing {
|
|
return errClosing
|
|
}
|
|
return errTimeout
|
|
}
|
|
|
|
func (pd *pollDesc) waitRead() error { return pd.wait('r') }
|
|
|
|
func (pd *pollDesc) waitWrite() error { return pd.wait('w') }
|
|
|
|
func (pd *pollDesc) waitCanceled(mode int) {}
|
|
|
|
func (pd *pollDesc) waitCanceledRead() {}
|
|
|
|
func (pd *pollDesc) waitCanceledWrite() {}
|
|
|
|
func (fd *netFD) setDeadline(t time.Time) error {
|
|
return setDeadlineImpl(fd, t, 'r'+'w')
|
|
}
|
|
|
|
func (fd *netFD) setReadDeadline(t time.Time) error {
|
|
return setDeadlineImpl(fd, t, 'r')
|
|
}
|
|
|
|
func (fd *netFD) setWriteDeadline(t time.Time) error {
|
|
return setDeadlineImpl(fd, t, 'w')
|
|
}
|
|
|
|
func setDeadlineImpl(fd *netFD, t time.Time, mode int) error {
|
|
d := t.UnixNano()
|
|
if t.IsZero() {
|
|
d = 0
|
|
}
|
|
if err := fd.incref(); err != nil {
|
|
return err
|
|
}
|
|
switch mode {
|
|
case 'r':
|
|
syscall.SetReadDeadline(fd.sysfd, d)
|
|
case 'w':
|
|
syscall.SetWriteDeadline(fd.sysfd, d)
|
|
case 'r' + 'w':
|
|
syscall.SetReadDeadline(fd.sysfd, d)
|
|
syscall.SetWriteDeadline(fd.sysfd, d)
|
|
}
|
|
fd.decref()
|
|
return nil
|
|
}
|