libgo patch committed: Fix fd_select.go

Submitted by Ian Taylor on March 28, 2011, 6:35 p.m.

Details

Message ID mcrtyenay9f.fsf@google.com
State New
Headers show

Commit Message

Ian Taylor March 28, 2011, 6:35 p.m.
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

Patch hide | download patch | download mbox

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
 	}