This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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
 	}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]