diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/rpc.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/src/rpc.cpp b/src/rpc.cpp index 4ff09b9..a4b53ca 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp | |||
| @@ -4697,6 +4697,31 @@ static void PoolEventLoop() | |||
| 4697 | sock_close(fd); | 4697 | sock_close(fd); |
| 4698 | continue; | 4698 | continue; |
| 4699 | } | 4699 | } |
| 4700 | // #26: select() + FD_SET goes undefined once we exceed what an | ||
| 4701 | // fd_set can carry, and MAX_POOL_MINERS (1000) alone does not | ||
| 4702 | // prevent it -- a Miner is only removed on clean disconnect, so | ||
| 4703 | // half-open zombies accumulate and the OS can hand out fds past | ||
| 4704 | // the limit long before the count reaches 1000. Refuse rather | ||
| 4705 | // than corrupt the fd_set. Which limit applies is platform | ||
| 4706 | // specific: POSIX bounds the descriptor value, Windows the | ||
| 4707 | // number of SOCKET handles an fd_set can hold. | ||
| 4708 | #ifndef _WIN32 | ||
| 4709 | if ((int)fd >= (int)FD_SETSIZE) { | ||
| 4710 | LogPrint("worker", "[pool] refusing miner fd=%d -- at/over" | ||
| 4711 | " FD_SETSIZE=%d, select() would be undefined (#26)\n", | ||
| 4712 | (int)fd, (int)FD_SETSIZE); | ||
| 4713 | sock_close(fd); | ||
| 4714 | continue; | ||
| 4715 | } | ||
| 4716 | #else | ||
| 4717 | if (gMiners.size() >= (size_t)FD_SETSIZE) { | ||
| 4718 | LogPrint("worker", "[pool] refusing miner -- %zu sockets held," | ||
| 4719 | " an fd_set carries at most FD_SETSIZE=%d (#26)\n", | ||
| 4720 | gMiners.size(), (int)FD_SETSIZE); | ||
| 4721 | sock_close(fd); | ||
| 4722 | continue; | ||
| 4723 | } | ||
| 4724 | #endif | ||
| 4700 | gMiners.push_back(new Miner(fd)); | 4725 | gMiners.push_back(new Miner(fd)); |
| 4701 | LogPrint("worker", "[pool] miner fd=%d entered event loop" | 4726 | LogPrint("worker", "[pool] miner fd=%d entered event loop" |
| 4702 | " -- awaiting subscribe/authorize\n", (int)fd); | 4727 | " -- awaiting subscribe/authorize\n", (int)fd); |