Patchwork libgo patch committed: Check for EINTR in network code

login
register
mail settings
Submitter Ian Taylor
Date Jan. 26, 2011, 10:37 p.m.
Message ID <mcr62tbuw9w.fsf@google.com>
Download mbox | patch
Permalink /patch/80563/
State New
Headers show

Comments

Ian Taylor - Jan. 26, 2011, 10:37 p.m.
Since gccgo uses signals to manage garbage collection, having a system
call return EINTR most likely just means that the garbage collector
ran.  This patch fixes the networking code in libgo to just retry after
getting EINTR.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian

Patch

diff -r 03b7a29fede7 libgo/go/net/fd.go
--- a/libgo/go/net/fd.go	Wed Jan 26 11:49:54 2011 -0800
+++ b/libgo/go/net/fd.go	Wed Jan 26 14:35:06 2011 -0800
@@ -350,7 +350,7 @@ 
 	for {
 		var errno int
 		n, errno = syscall.Read(fd.sysfile.Fd(), p)
-		if errno == syscall.EAGAIN && fd.rdeadline >= 0 {
+		if (errno == syscall.EAGAIN || errno == syscall.EINTR) && fd.rdeadline >= 0 {
 			pollserver.WaitRead(fd)
 			continue
 		}
@@ -385,7 +385,7 @@ 
 	for {
 		var errno int
 		n, sa, errno = syscall.Recvfrom(fd.sysfd, p, 0)
-		if errno == syscall.EAGAIN && fd.rdeadline >= 0 {
+		if (errno == syscall.EAGAIN || errno == syscall.EINTR) && fd.rdeadline >= 0 {
 			pollserver.WaitRead(fd)
 			continue
 		}
@@ -418,7 +418,7 @@ 
 	for {
 		var errno int
 		n, oobn, flags, sa, errno = syscall.Recvmsg(fd.sysfd, p, oob, 0)
-		if errno == syscall.EAGAIN && fd.rdeadline >= 0 {
+		if (errno == syscall.EAGAIN || errno == syscall.EINTR) && fd.rdeadline >= 0 {
 			pollserver.WaitRead(fd)
 			continue
 		}
@@ -464,7 +464,7 @@ 
 		if nn == len(p) {
 			break
 		}
-		if errno == syscall.EAGAIN && fd.wdeadline >= 0 {
+		if (errno == syscall.EAGAIN || errno == syscall.EINTR) && fd.wdeadline >= 0 {
 			pollserver.WaitWrite(fd)
 			continue
 		}
@@ -500,7 +500,7 @@ 
 	var oserr os.Error
 	for {
 		errno := syscall.Sendto(fd.sysfd, p, 0, sa)
-		if errno == syscall.EAGAIN && fd.wdeadline >= 0 {
+		if (errno == syscall.EAGAIN || errno == syscall.EINTR) && fd.wdeadline >= 0 {
 			pollserver.WaitWrite(fd)
 			continue
 		}
@@ -534,7 +534,7 @@ 
 	for {
 		var errno int
 		errno = syscall.Sendmsg(fd.sysfd, p, oob, sa, 0)
-		if errno == syscall.EAGAIN && fd.wdeadline >= 0 {
+		if (errno == syscall.EAGAIN || errno == syscall.EINTR) && fd.wdeadline >= 0 {
 			pollserver.WaitWrite(fd)
 			continue
 		}
@@ -572,7 +572,7 @@ 
 			return nil, os.EINVAL
 		}
 		s, sa, e = syscall.Accept(fd.sysfd)
-		if e != syscall.EAGAIN {
+		if e != syscall.EAGAIN && e != syscall.EINTR {
 			break
 		}
 		syscall.ForkLock.RUnlock()