re PR go/48312 (http, rpc, websocket tests hang on Solaris 2/x86)

PR go/48312
Fix fd_select.go for changes in FD handling.

We have to wake up the goroutine waiting in select each time
we change the set of descriptors we are waiting for, unlike
epoll.

From-SVN: r171623
This commit is contained in:
Ian Lance Taylor 2011-03-28 18:35:53 +00:00
parent 520af9ec9a
commit efbb12ae8a
5 changed files with 20 additions and 9 deletions

View File

@ -122,9 +122,13 @@ func (s *pollServer) AddFD(fd *netFD, mode int) {
doWakeup = true doWakeup = true
} }
if err := s.poll.AddFD(intfd, mode, false); err != nil { wake, err := s.poll.AddFD(intfd, mode, false)
if err != nil {
panic("pollServer AddFD " + err.String()) panic("pollServer AddFD " + err.String())
} }
if wake {
doWakeup = true
}
s.Unlock() s.Unlock()

View File

@ -47,7 +47,7 @@ func newpollster() (p *pollster, err os.Error) {
return p, nil return p, nil
} }
func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error { func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, os.Error) {
// pollServer is locked. // pollServer is locked.
var already bool var already bool
@ -69,10 +69,10 @@ func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error {
op = syscall.EPOLL_CTL_ADD op = syscall.EPOLL_CTL_ADD
} }
if e := syscall.EpollCtl(p.epfd, op, fd, &p.ctlEvent); e != 0 { if e := syscall.EpollCtl(p.epfd, op, fd, &p.ctlEvent); e != 0 {
return os.NewSyscallError("epoll_ctl", e) return false, os.NewSyscallError("epoll_ctl", e)
} }
p.events[fd] = p.ctlEvent.Events p.events[fd] = p.ctlEvent.Events
return nil return false, nil
} }
func (p *pollster) StopWaiting(fd int, bits uint) { func (p *pollster) StopWaiting(fd int, bits uint) {

View File

@ -32,7 +32,9 @@ func newpollster() (p *pollster, err os.Error) {
return p, nil return p, nil
} }
func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error { func (p *pollster) AddFD(fd int, mode int, repeat bool) (bool, os.Error) {
// pollServer is locked.
if mode == 'r' { if mode == 'r' {
syscall.FDSet(fd, p.readFds) syscall.FDSet(fd, p.readFds)
} else { } else {
@ -47,10 +49,12 @@ func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error {
p.maxFd = fd p.maxFd = fd
} }
return nil return true, nil
} }
func (p *pollster) DelFD(fd int, mode int) { func (p *pollster) DelFD(fd int, mode int) {
// pollServer is locked.
if mode == 'r' { if mode == 'r' {
if !syscall.FDIsSet(fd, p.readFds) { if !syscall.FDIsSet(fd, p.readFds) {
print("Select unexpected fd=", fd, " for read\n") print("Select unexpected fd=", fd, " for read\n")
@ -71,7 +75,7 @@ func (p *pollster) DelFD(fd int, mode int) {
// We don't worry about maxFd here. // We don't worry about maxFd here.
} }
func (p *pollster) WaitFD(nsec int64) (fd int, mode int, err os.Error) { func (p *pollster) WaitFD(s *pollServer, nsec int64) (fd int, mode int, err os.Error) {
if p.nReady == 0 { if p.nReady == 0 {
var timeout *syscall.Timeval var timeout *syscall.Timeval
var tv syscall.Timeval var tv syscall.Timeval
@ -89,7 +93,10 @@ func (p *pollster) WaitFD(nsec int64) (fd int, mode int, err os.Error) {
tmpReadFds = *p.readFds tmpReadFds = *p.readFds
tmpWriteFds = *p.writeFds tmpWriteFds = *p.writeFds
s.Unlock()
n, e = syscall.Select(p.maxFd + 1, &tmpReadFds, &tmpWriteFds, nil, timeout) n, e = syscall.Select(p.maxFd + 1, &tmpReadFds, &tmpWriteFds, nil, timeout)
s.Lock()
if e != syscall.EINTR { if e != syscall.EINTR {
break break
} }

View File

@ -31,7 +31,7 @@ func newPollServer() (s *pollServer, err os.Error) {
if s.poll, err = newpollster(); err != nil { if s.poll, err = newpollster(); err != nil {
goto Error goto Error
} }
if err = s.poll.AddFD(s.pr.Fd(), 'r', true); err != nil { if _, err = s.poll.AddFD(s.pr.Fd(), 'r', true); err != nil {
s.poll.Close() s.poll.Close()
goto Error goto Error
} }

View File

@ -68,7 +68,7 @@ func newPollServer() (s *pollServer, err os.Error) {
if s.poll, err = newpollster(); err != nil { if s.poll, err = newpollster(); err != nil {
goto Error goto Error
} }
if err = s.poll.AddFD(s.pr.Fd(), 'r', true); err != nil { if _, err = s.poll.AddFD(s.pr.Fd(), 'r', true); err != nil {
s.poll.Close() s.poll.Close()
goto Error goto Error
} }