From 7c4f14f941b361e97dd87afd215735c1cee1d81f Mon Sep 17 00:00:00 2001 From: Benjamin Sergeant Date: Tue, 1 Jan 2019 16:11:27 -0800 Subject: [PATCH] thread accepting connections can be cancelled/stopped externally --- examples/echo_server/echo_server.cpp | 1 + ixwebsocket/IXWebSocketServer.cpp | 34 +++++++++++++++++++++++----- ixwebsocket/IXWebSocketServer.h | 5 ++++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/examples/echo_server/echo_server.cpp b/examples/echo_server/echo_server.cpp index 16eb979d..7b5f5f4e 100644 --- a/examples/echo_server/echo_server.cpp +++ b/examples/echo_server/echo_server.cpp @@ -67,6 +67,7 @@ int main(int argc, char** argv) } server.start(); + server.wait(); return 0; } diff --git a/ixwebsocket/IXWebSocketServer.cpp b/ixwebsocket/IXWebSocketServer.cpp index 3aa5cfc0..996fa497 100644 --- a/ixwebsocket/IXWebSocketServer.cpp +++ b/ixwebsocket/IXWebSocketServer.cpp @@ -7,6 +7,7 @@ #include "IXWebSocketServer.h" #include "IXWebSocketTransport.h" #include "IXWebSocket.h" +#include "IXSocketConnect.h" #include #include @@ -120,32 +121,53 @@ namespace ix _thread = std::thread(&WebSocketServer::run, this); } + void WebSocketServer::wait() + { + std::unique_lock lock(_conditionVariableMutex); + _conditionVariable.wait(lock); + } + // FIXME: we should cancel all the async per connections tasks void WebSocketServer::stop() { _stop = true; _thread.join(); _stop = false; + + _conditionVariable.notify_one(); } void WebSocketServer::run() { + // Set the socket to non blocking mode, so that accept calls are not blocking + SocketConnect::configure(_serverFd); + std::future f; for (;;) { + if (_stop) return; + // Accept a connection. struct sockaddr_in client; // client address information int clientFd; // socket connected to client socklen_t addressLen = sizeof(socklen_t); - if ((clientFd = accept(_serverFd, (struct sockaddr *)&client, &addressLen)) == -1) + if ((clientFd = accept(_serverFd, (struct sockaddr *)&client, &addressLen)) < 0) { - // FIXME: that error should be propagated - std::stringstream ss; - ss << "WebSocketServer::run() error accepting connection: " - << strerror(errno); - logError(ss.str()); + if (errno == EWOULDBLOCK) + { + std::chrono::duration wait(10); + std::this_thread::sleep_for(wait); + } + else + { + // FIXME: that error should be propagated + std::stringstream ss; + ss << "WebSocketServer::run() error accepting connection: " + << strerror(errno); + logError(ss.str()); + } continue; } diff --git a/ixwebsocket/IXWebSocketServer.h b/ixwebsocket/IXWebSocketServer.h index 3750eb4e..74f9e644 100644 --- a/ixwebsocket/IXWebSocketServer.h +++ b/ixwebsocket/IXWebSocketServer.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "IXWebSocket.h" @@ -29,6 +30,7 @@ namespace ix void setOnConnectionCallback(const OnConnectionCallback& callback); void start(); + void wait(); std::pair listen(); @@ -54,6 +56,9 @@ namespace ix std::atomic _stop; std::thread _thread; + std::condition_variable _conditionVariable; + std::mutex _conditionVariableMutex; + const static std::string kDefaultHost; // Methods