re PR go/59433 (Many 64-bit Go tests SEGV on Solaris)
PR go/59433 net: Don't use stack space for fd_sets when using select. From-SVN: r206411
This commit is contained in:
parent
06f4627b30
commit
2da4a7611b
1 changed files with 45 additions and 16 deletions
|
@ -118,10 +118,15 @@ runtime_netpollclose(uintptr fd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Used to avoid using too much stack memory. */
|
||||||
|
static bool inuse;
|
||||||
|
static fd_set grfds, gwfds, gefds, gtfds;
|
||||||
|
|
||||||
G*
|
G*
|
||||||
runtime_netpoll(bool block)
|
runtime_netpoll(bool block)
|
||||||
{
|
{
|
||||||
fd_set rfds, wfds, efds, tfds;
|
fd_set *prfds, *pwfds, *pefds, *ptfds;
|
||||||
|
bool allocatedfds;
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
struct timeval *pt;
|
struct timeval *pt;
|
||||||
int max, c, i;
|
int max, c, i;
|
||||||
|
@ -140,37 +145,52 @@ runtime_netpoll(bool block)
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
__builtin_memcpy(&rfds, &fds, sizeof fds);
|
if(inuse) {
|
||||||
|
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;
|
||||||
|
pefds = &gefds;
|
||||||
|
ptfds = >fds;
|
||||||
|
inuse = true;
|
||||||
|
allocatedfds = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
__builtin_memcpy(prfds, &fds, sizeof fds);
|
||||||
|
|
||||||
runtime_unlock(&selectlock);
|
runtime_unlock(&selectlock);
|
||||||
|
|
||||||
__builtin_memcpy(&wfds, &rfds, sizeof fds);
|
__builtin_memcpy(pwfds, prfds, sizeof fds);
|
||||||
FD_CLR(rdwake, &wfds);
|
FD_CLR(rdwake, pwfds);
|
||||||
__builtin_memcpy(&efds, &wfds, sizeof fds);
|
__builtin_memcpy(pefds, pwfds, sizeof fds);
|
||||||
|
|
||||||
__builtin_memcpy(&tfds, &wfds, sizeof fds);
|
__builtin_memcpy(ptfds, pwfds, sizeof fds);
|
||||||
|
|
||||||
__builtin_memset(&timeout, 0, sizeof timeout);
|
__builtin_memset(&timeout, 0, sizeof timeout);
|
||||||
pt = &timeout;
|
pt = &timeout;
|
||||||
if(block)
|
if(block)
|
||||||
pt = nil;
|
pt = nil;
|
||||||
|
|
||||||
c = select(max, &rfds, &wfds, &efds, pt);
|
c = select(max, prfds, pwfds, pefds, pt);
|
||||||
if(c < 0) {
|
if(c < 0) {
|
||||||
if(errno == EBADF) {
|
if(errno == EBADF) {
|
||||||
// Some file descriptor has been closed.
|
// Some file descriptor has been closed.
|
||||||
// Check each one, and treat each closed
|
// Check each one, and treat each closed
|
||||||
// descriptor as ready for read/write.
|
// descriptor as ready for read/write.
|
||||||
c = 0;
|
c = 0;
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(prfds);
|
||||||
FD_ZERO(&wfds);
|
FD_ZERO(pwfds);
|
||||||
FD_ZERO(&efds);
|
FD_ZERO(pefds);
|
||||||
for(i = 0; i < max; i++) {
|
for(i = 0; i < max; i++) {
|
||||||
if(FD_ISSET(i, &tfds)
|
if(FD_ISSET(i, ptfds)
|
||||||
&& fstat(i, &st) < 0
|
&& fstat(i, &st) < 0
|
||||||
&& errno == EBADF) {
|
&& errno == EBADF) {
|
||||||
FD_SET(i, &rfds);
|
FD_SET(i, prfds);
|
||||||
FD_SET(i, &wfds);
|
FD_SET(i, pwfds);
|
||||||
c += 2;
|
c += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,15 +204,15 @@ runtime_netpoll(bool block)
|
||||||
gp = nil;
|
gp = nil;
|
||||||
for(i = 0; i < max && c > 0; i++) {
|
for(i = 0; i < max && c > 0; i++) {
|
||||||
mode = 0;
|
mode = 0;
|
||||||
if(FD_ISSET(i, &rfds)) {
|
if(FD_ISSET(i, prfds)) {
|
||||||
mode += 'r';
|
mode += 'r';
|
||||||
--c;
|
--c;
|
||||||
}
|
}
|
||||||
if(FD_ISSET(i, &wfds)) {
|
if(FD_ISSET(i, pwfds)) {
|
||||||
mode += 'w';
|
mode += 'w';
|
||||||
--c;
|
--c;
|
||||||
}
|
}
|
||||||
if(FD_ISSET(i, &efds)) {
|
if(FD_ISSET(i, pefds)) {
|
||||||
mode = 'r' + 'w';
|
mode = 'r' + 'w';
|
||||||
--c;
|
--c;
|
||||||
}
|
}
|
||||||
|
@ -213,6 +233,15 @@ runtime_netpoll(bool block)
|
||||||
}
|
}
|
||||||
if(block && gp == nil)
|
if(block && gp == nil)
|
||||||
goto retry;
|
goto retry;
|
||||||
|
|
||||||
|
if(allocatedfds) {
|
||||||
|
runtime_SysFree(prfds, 4 * sizeof fds, &mstats.other_sys);
|
||||||
|
} else {
|
||||||
|
runtime_lock(&selectlock);
|
||||||
|
inuse = false;
|
||||||
|
runtime_unlock(&selectlock);
|
||||||
|
}
|
||||||
|
|
||||||
return gp;
|
return gp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue