diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-02-06 22:40:18 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-02-06 22:40:18 +0000 |
commit | d617bce48cdc251c0b8c07713c03065d9c122aa2 (patch) | |
tree | c583f9846d43da4bd06b379bb1f0296b4b5a43f0 /libgo | |
parent | b96299a1353eae165dc0693b4917b4d757675b9d (diff) | |
download | gcc-d617bce48cdc251c0b8c07713c03065d9c122aa2.tar.gz |
re PR go/56172 (net FAILs on Solaris)
PR go/56172
net: Fixes for select based pollster.
Make Close work properly, mainly for testing. Restart the
select if a descriptor is closed.
From-SVN: r195823
Diffstat (limited to 'libgo')
-rw-r--r-- | libgo/go/net/fd_bsd.go | 3 | ||||
-rw-r--r-- | libgo/go/net/fd_linux.go | 3 | ||||
-rw-r--r-- | libgo/go/net/fd_select.go | 23 | ||||
-rw-r--r-- | libgo/go/net/fd_unix.go | 12 |
4 files changed, 34 insertions, 7 deletions
diff --git a/libgo/go/net/fd_bsd.go b/libgo/go/net/fd_bsd.go index 4f5dd6e524a..f5a55bb44a7 100644 --- a/libgo/go/net/fd_bsd.go +++ b/libgo/go/net/fd_bsd.go @@ -64,7 +64,7 @@ func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) { return false, nil } -func (p *pollster) DelFD(fd int, mode int) { +func (p *pollster) DelFD(fd int, mode int) bool { // pollServer is locked. var kmode int @@ -77,6 +77,7 @@ func (p *pollster) DelFD(fd int, mode int) { // EV_DELETE - delete event from kqueue list syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE) syscall.Kevent(p.kq, p.kbuf[:], nil, nil) + return false } func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) { diff --git a/libgo/go/net/fd_linux.go b/libgo/go/net/fd_linux.go index 085e423072a..8ecbff8bdf0 100644 --- a/libgo/go/net/fd_linux.go +++ b/libgo/go/net/fd_linux.go @@ -114,7 +114,7 @@ func (p *pollster) StopWaiting(fd int, bits uint) { } } -func (p *pollster) DelFD(fd int, mode int) { +func (p *pollster) DelFD(fd int, mode int) bool { // pollServer is locked. if mode == 'r' { @@ -133,6 +133,7 @@ func (p *pollster) DelFD(fd int, mode int) { i++ } } + return false } func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) { diff --git a/libgo/go/net/fd_select.go b/libgo/go/net/fd_select.go index 22db1cbcac2..4103c57e2cb 100644 --- a/libgo/go/net/fd_select.go +++ b/libgo/go/net/fd_select.go @@ -7,6 +7,7 @@ package net import ( + "errors" "os" "syscall" ) @@ -17,6 +18,7 @@ type pollster struct { readyReadFds, readyWriteFds *syscall.FdSet nReady int lastFd int + closed bool } func newpollster() (p *pollster, err error) { @@ -35,6 +37,10 @@ func newpollster() (p *pollster, err error) { func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) { // pollServer is locked. + if p.closed { + return false, errors.New("pollster closed") + } + if mode == 'r' { syscall.FDSet(fd, p.readFds) } else { @@ -52,19 +58,23 @@ func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, error) { return true, nil } -func (p *pollster) DelFD(fd int, mode int) { +func (p *pollster) DelFD(fd int, mode int) bool { // pollServer is locked. + if p.closed { + return false + } + if mode == 'r' { if !syscall.FDIsSet(fd, p.readFds) { print("Select unexpected fd=", fd, " for read\n") - return + return false } syscall.FDClr(fd, p.readFds) } else { if !syscall.FDIsSet(fd, p.writeFds) { print("Select unexpected fd=", fd, " for write\n") - return + return false } syscall.FDClr(fd, p.writeFds) } @@ -73,6 +83,8 @@ func (p *pollster) DelFD(fd int, mode int) { syscall.FDClr(fd, p.repeatFds) // We don't worry about maxFd here. + + return true } func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err error) { @@ -89,6 +101,10 @@ func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err erro var e error var tmpReadFds, tmpWriteFds syscall.FdSet for { + if p.closed { + return -1, 0, errors.New("pollster closed") + } + // Temporary syscall.FdSet's into which the values are copied // because select mutates the values. tmpReadFds = *p.readFds @@ -161,5 +177,6 @@ func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err erro } func (p *pollster) Close() error { + p.closed = true return nil } diff --git a/libgo/go/net/fd_unix.go b/libgo/go/net/fd_unix.go index e9d2e4165f1..42b0c74f218 100644 --- a/libgo/go/net/fd_unix.go +++ b/libgo/go/net/fd_unix.go @@ -110,16 +110,24 @@ func (s *pollServer) AddFD(fd *netFD, mode int) error { // any I/O running on fd. The caller must have locked // pollserver. func (s *pollServer) Evict(fd *netFD) { + doWakeup := false if s.pending[fd.sysfd<<1] == fd { s.WakeFD(fd, 'r', errClosing) - s.poll.DelFD(fd.sysfd, 'r') + if s.poll.DelFD(fd.sysfd, 'r') { + doWakeup = true + } delete(s.pending, fd.sysfd<<1) } if s.pending[fd.sysfd<<1|1] == fd { s.WakeFD(fd, 'w', errClosing) - s.poll.DelFD(fd.sysfd, 'w') + if s.poll.DelFD(fd.sysfd, 'w') { + doWakeup = true + } delete(s.pending, fd.sysfd<<1|1) } + if doWakeup { + s.Wakeup() + } } var wakeupbuf [1]byte |