This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
libgo patch committed: Fix fd_select.go
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org, gofrontend-dev at googlegroups dot com
- Date: Mon, 28 Mar 2011 11:35:56 -0700
- Subject: libgo patch committed: Fix fd_select.go
This patch fixes fd_select.go for the changes in FD handling in the
latest libgo update. The code in libgo now takes advantage of the fact
that if you change the set of descriptors used by epoll, it is not
necessary to wake up the thread waiting in epoll_wait. That is not true
of select: if you change the set of descriptors, you do have to wake up
the select. This patch implements that. Bootstrapped on
x86_64-unknown-linux-gnu. Ran Go testsuite using fd_select.go instead
of fd_linux.go. Committed to mainline. This fixes PR go/48312.
Ian
diff -r 056f7c9c13f8 libgo/go/net/fd.go
--- a/libgo/go/net/fd.go Mon Mar 28 11:28:45 2011 -0700
+++ b/libgo/go/net/fd.go Mon Mar 28 11:30:46 2011 -0700
@@ -122,9 +122,13 @@
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())
}
+ if wake {
+ doWakeup = true
+ }
s.Unlock()
diff -r 056f7c9c13f8 libgo/go/net/fd_linux.go
--- a/libgo/go/net/fd_linux.go Mon Mar 28 11:28:45 2011 -0700
+++ b/libgo/go/net/fd_linux.go Mon Mar 28 11:30:46 2011 -0700
@@ -47,7 +47,7 @@
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.
var already bool
@@ -69,10 +69,10 @@
op = syscall.EPOLL_CTL_ADD
}
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
- return nil
+ return false, nil
}
func (p *pollster) StopWaiting(fd int, bits uint) {
diff -r 056f7c9c13f8 libgo/go/net/fd_select.go
--- a/libgo/go/net/fd_select.go Mon Mar 28 11:28:45 2011 -0700
+++ b/libgo/go/net/fd_select.go Mon Mar 28 11:30:46 2011 -0700
@@ -32,7 +32,9 @@
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' {
syscall.FDSet(fd, p.readFds)
} else {
@@ -47,10 +49,12 @@
p.maxFd = fd
}
- return nil
+ return true, nil
}
func (p *pollster) DelFD(fd int, mode int) {
+ // pollServer is locked.
+
if mode == 'r' {
if !syscall.FDIsSet(fd, p.readFds) {
print("Select unexpected fd=", fd, " for read\n")
@@ -71,7 +75,7 @@
// 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 {
var timeout *syscall.Timeval
var tv syscall.Timeval
@@ -89,7 +93,10 @@
tmpReadFds = *p.readFds
tmpWriteFds = *p.writeFds
+ s.Unlock()
n, e = syscall.Select(p.maxFd + 1, &tmpReadFds, &tmpWriteFds, nil, timeout)
+ s.Lock()
+
if e != syscall.EINTR {
break
}
diff -r 056f7c9c13f8 libgo/go/net/newpollserver.go
--- a/libgo/go/net/newpollserver.go Mon Mar 28 11:28:45 2011 -0700
+++ b/libgo/go/net/newpollserver.go Mon Mar 28 11:30:46 2011 -0700
@@ -31,7 +31,7 @@
if s.poll, err = newpollster(); err != nil {
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()
goto Error
}
diff -r 056f7c9c13f8 libgo/go/net/newpollserver_rtems.go
--- a/libgo/go/net/newpollserver_rtems.go Mon Mar 28 11:28:45 2011 -0700
+++ b/libgo/go/net/newpollserver_rtems.go Mon Mar 28 11:30:46 2011 -0700
@@ -68,7 +68,7 @@
if s.poll, err = newpollster(); err != nil {
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()
goto Error
}