On systems that use select (basically, Solaris), the netpoll code in libgo could sometimes fail to free an fd_set that it allocated. Over time, this could cause the program to run out of memory. This patch fixes that problem. It also skips an unnecessary call to read. Bootstrapped and ran Go tests on i386 Solaris 10. This fixes PR 61303. Committed to mainline and GCC 5 branch.
Ian
Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 230776) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -0d979f0b860cfd879754150e0ae5e1018b94d7c4 +81eb6a3f425b2158c67ee32c0cc973a72ce9d6be The first line of this file holds the git revision number of the last merge done from the gofrontend repository. Index: libgo/runtime/netpoll_select.c =================================================================== --- libgo/runtime/netpoll_select.c (revision 230759) +++ libgo/runtime/netpoll_select.c (working copy) @@ -135,6 +135,8 @@ runtime_netpoll(bool block) byte b; struct stat st; + allocatedfds = false; + retry: runtime_lock(&selectlock); @@ -146,11 +148,13 @@ runtime_netpoll(bool block) } if(inuse) { - prfds = runtime_SysAlloc(4 * sizeof fds, &mstats.other_sys); - pwfds = prfds + 1; - pefds = pwfds + 1; - ptfds = pefds + 1; - allocatedfds = true; + if(!allocatedfds) { + prfds = runtime_SysAlloc(4 * sizeof fds, &mstats.other_sys); + pwfds = prfds + 1; + pefds = pwfds + 1; + ptfds = pefds + 1; + allocatedfds = true; + } } else { prfds = &grfds; pwfds = &gwfds; @@ -216,7 +220,7 @@ runtime_netpoll(bool block) mode = 'r' + 'w'; --c; } - if(i == rdwake) { + if(i == rdwake && mode != 0) { while(read(rdwake, &b, sizeof b) > 0) ; continue;