The cooperative threading model used by Go works by calling entersyscall whenever we are about to make a call to a C function that may block. That was not being done for a call to getaddrinfo used when doing a DNS lookup. This patch fixes that problem by exporting the entersyscall and exitsyscall functions from the syscall package. Exporting a function in Go is done by naming it with a capital letter, so this patch simply consistently renames the entersyscall and exitsyscall functions and all their uses. This will also be useful for SWIG, which faces a similar issue.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline. OK for 4.7 branch? Thanks. Ian
diff -r 89c0a966e4d6 libgo/go/net/cgo_unix.go --- a/libgo/go/net/cgo_unix.go Tue Mar 13 13:54:11 2012 -0700 +++ b/libgo/go/net/cgo_unix.go Tue Mar 13 15:56:25 2012 -0700 @@ -75,7 +75,10 @@ } s := syscall.StringBytePtr(service) - if libc_getaddrinfo(nil, s, &hints, &res) == 0 { + syscall.Entersyscall() + gerrno := libc_getaddrinfo(nil, s, &hints, &res) + syscall.Exitsyscall() + if gerrno == 0 { defer libc_freeaddrinfo(res) for r := res; r != nil; r = r.Ai_next { switch r.Ai_family { @@ -108,7 +111,9 @@ hints.Ai_flags = int32((syscall.AI_ALL | syscall.AI_V4MAPPED | syscall.AI_CANONNAME) & cgoAddrInfoMask()) h := syscall.StringBytePtr(name) + syscall.Entersyscall() gerrno := libc_getaddrinfo(h, nil, &hints, &res) + syscall.Exitsyscall() if gerrno != 0 { var str string if gerrno == syscall.EAI_NONAME { diff -r 89c0a966e4d6 libgo/go/syscall/libcall_linux.go --- a/libgo/go/syscall/libcall_linux.go Tue Mar 13 13:54:11 2012 -0700 +++ b/libgo/go/syscall/libcall_linux.go Tue Mar 13 15:56:25 2012 -0700 @@ -202,13 +202,13 @@ } else { p = (*byte)(unsafe.Pointer(&_zero)) } - entersyscall() + Entersyscall() r1, _, errno := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(len(buf))) n = int(r1) if n < 0 { err = errno } - exitsyscall() + Exitsyscall() return } diff -r 89c0a966e4d6 libgo/go/syscall/libcall_support.go --- a/libgo/go/syscall/libcall_support.go Tue Mar 13 13:54:11 2012 -0700 +++ b/libgo/go/syscall/libcall_support.go Tue Mar 13 15:56:25 2012 -0700 @@ -6,7 +6,7 @@ package syscall -func entersyscall() -func exitsyscall() +func Entersyscall() +func Exitsyscall() func GetErrno() Errno func SetErrno(Errno) diff -r 89c0a966e4d6 libgo/go/syscall/mksyscall.awk --- a/libgo/go/syscall/mksyscall.awk Tue Mar 13 13:54:11 2012 -0700 +++ b/libgo/go/syscall/mksyscall.awk Tue Mar 13 15:56:25 2012 -0700 @@ -190,7 +190,7 @@ } if (blocking) { - print "\tentersyscall()" + print "\tEntersyscall()" } printf("\t") @@ -240,7 +240,7 @@ } if (blocking) { - print "\texitsyscall()" + print "\tExitsyscall()" } if (gofnresults != "") { diff -r 89c0a966e4d6 libgo/go/syscall/syscall_unix.go --- a/libgo/go/syscall/syscall_unix.go Tue Mar 13 13:54:11 2012 -0700 +++ b/libgo/go/syscall/syscall_unix.go Tue Mar 13 15:56:25 2012 -0700 @@ -30,7 +30,7 @@ // the arguments, so that we don't pass a 64-bit value when the function // expects a 32-bit one. func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { - entersyscall() + Entersyscall() var r uintptr if unsafe.Sizeof(r) == 4 { r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3), 0, 0, 0) @@ -40,12 +40,12 @@ r = uintptr(r1) } err = GetErrno() - exitsyscall() + Exitsyscall() return r, 0, err } func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { - entersyscall() + Entersyscall() var r uintptr if unsafe.Sizeof(r) == 4 { r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3), @@ -57,7 +57,7 @@ r = uintptr(r1) } err = GetErrno() - exitsyscall() + Exitsyscall() return r, 0, err } diff -r 89c0a966e4d6 libgo/runtime/runtime.h --- a/libgo/runtime/runtime.h Tue Mar 13 13:54:11 2012 -0700 +++ b/libgo/runtime/runtime.h Tue Mar 13 15:56:25 2012 -0700 @@ -298,8 +298,8 @@ void runtime_tsleep(int64); M* runtime_newm(void); void runtime_goexit(void); -void runtime_entersyscall(void) __asm__("libgo_syscall.syscall.entersyscall"); -void runtime_exitsyscall(void) __asm__("libgo_syscall.syscall.exitsyscall"); +void runtime_entersyscall(void) __asm__("libgo_syscall.syscall.Entersyscall"); +void runtime_exitsyscall(void) __asm__("libgo_syscall.syscall.Exitsyscall"); void siginit(void); bool __go_sigsend(int32 sig); int32 runtime_callers(int32, uintptr*, int32);