From 2aaf59651e573ad365d36e4dcbcdfed7204f6f44 Mon Sep 17 00:00:00 2001 From: Benjamin Sergeant Date: Sat, 15 Aug 2020 18:32:59 -0700 Subject: [PATCH] (socket server) in the loop accepting connections, call select without a timeout on unix to avoid busy looping, and only wake up when a new connection happens --- docs/CHANGELOG.md | 4 ++++ ixwebsocket/IXSocketServer.cpp | 24 ++++++++++++++++++++++-- ixwebsocket/IXWebSocketVersion.h | 2 +- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 5f070d33..8648c0df 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -2,6 +2,10 @@ All changes to this project will be documented in this file. +## [10.2.4] - 2020-08-15 + +(socket server) in the loop accepting connections, call select without a timeout on unix to avoid busy looping, and only wake up when a new connection happens + ## [10.2.3] - 2020-08-15 (socket server) instead of busy looping with a sleep, only wake up the GC thread when a new thread will have to be joined, (we know that thanks to the ConnectionState OnSetTerminated callback diff --git a/ixwebsocket/IXSocketServer.cpp b/ixwebsocket/IXSocketServer.cpp index c57acf05..b7affb8b 100644 --- a/ixwebsocket/IXSocketServer.cpp +++ b/ixwebsocket/IXSocketServer.cpp @@ -60,6 +60,16 @@ namespace ix std::pair SocketServer::listen() { + std::string acceptSelectInterruptInitErrorMsg; + if (!_acceptSelectInterrupt->init(acceptSelectInterruptInitErrorMsg)) + { + std::stringstream ss; + ss << "SocketServer::listen() error in SelectInterrupt::init: " + << acceptSelectInterruptInitErrorMsg; + + return std::make_pair(false, ss.str()); + } + if (_addressFamily != AF_INET && _addressFamily != AF_INET6) { std::string errMsg("SocketServer::listen() AF_INET and AF_INET6 are currently " @@ -195,7 +205,12 @@ namespace ix if (_thread.joinable()) { _stop = true; - _acceptSelectInterrupt->notify(SelectInterrupt::kCloseRequest); // Wake up select + // Wake up select + if (!_acceptSelectInterrupt->notify(SelectInterrupt::kCloseRequest)) + { + logError("SocketServer::stop: Cannot wake up from select"); + } + _thread.join(); _stop = false; } @@ -260,7 +275,12 @@ namespace ix if (_stop) return; // Use poll to check whether a new connection is in progress - int timeoutMs = 10; + int timeoutMs = -1; +#ifdef _WIN32 + // select cannot be interrupted on Windows so we need to pass a small timeout + timeoutMs = 10; +#endif + bool readyToRead = true; PollResultType pollResult = Socket::poll(readyToRead, timeoutMs, _serverFd, _acceptSelectInterrupt); diff --git a/ixwebsocket/IXWebSocketVersion.h b/ixwebsocket/IXWebSocketVersion.h index e659c34d..8fb61ea6 100644 --- a/ixwebsocket/IXWebSocketVersion.h +++ b/ixwebsocket/IXWebSocketVersion.h @@ -6,4 +6,4 @@ #pragma once -#define IX_WEBSOCKET_VERSION "10.2.3" +#define IX_WEBSOCKET_VERSION "10.2.4"