thread accepting connections can be cancelled/stopped externally

This commit is contained in:
Benjamin Sergeant 2019-01-01 16:11:27 -08:00
parent ead54d6c37
commit 7c4f14f941
3 changed files with 34 additions and 6 deletions

View File

@ -67,6 +67,7 @@ int main(int argc, char** argv)
} }
server.start(); server.start();
server.wait();
return 0; return 0;
} }

View File

@ -7,6 +7,7 @@
#include "IXWebSocketServer.h" #include "IXWebSocketServer.h"
#include "IXWebSocketTransport.h" #include "IXWebSocketTransport.h"
#include "IXWebSocket.h" #include "IXWebSocket.h"
#include "IXSocketConnect.h"
#include <sstream> #include <sstream>
#include <future> #include <future>
@ -120,32 +121,53 @@ namespace ix
_thread = std::thread(&WebSocketServer::run, this); _thread = std::thread(&WebSocketServer::run, this);
} }
void WebSocketServer::wait()
{
std::unique_lock<std::mutex> lock(_conditionVariableMutex);
_conditionVariable.wait(lock);
}
// FIXME: we should cancel all the async per connections tasks // FIXME: we should cancel all the async per connections tasks
void WebSocketServer::stop() void WebSocketServer::stop()
{ {
_stop = true; _stop = true;
_thread.join(); _thread.join();
_stop = false; _stop = false;
_conditionVariable.notify_one();
} }
void WebSocketServer::run() void WebSocketServer::run()
{ {
// Set the socket to non blocking mode, so that accept calls are not blocking
SocketConnect::configure(_serverFd);
std::future<void> f; std::future<void> f;
for (;;) for (;;)
{ {
if (_stop) return;
// Accept a connection. // Accept a connection.
struct sockaddr_in client; // client address information struct sockaddr_in client; // client address information
int clientFd; // socket connected to client int clientFd; // socket connected to client
socklen_t addressLen = sizeof(socklen_t); socklen_t addressLen = sizeof(socklen_t);
if ((clientFd = accept(_serverFd, (struct sockaddr *)&client, &addressLen)) == -1) if ((clientFd = accept(_serverFd, (struct sockaddr *)&client, &addressLen)) < 0)
{
if (errno == EWOULDBLOCK)
{
std::chrono::duration<double, std::milli> wait(10);
std::this_thread::sleep_for(wait);
}
else
{ {
// FIXME: that error should be propagated // FIXME: that error should be propagated
std::stringstream ss; std::stringstream ss;
ss << "WebSocketServer::run() error accepting connection: " ss << "WebSocketServer::run() error accepting connection: "
<< strerror(errno); << strerror(errno);
logError(ss.str()); logError(ss.str());
}
continue; continue;
} }

View File

@ -13,6 +13,7 @@
#include <mutex> #include <mutex>
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <condition_variable>
#include "IXWebSocket.h" #include "IXWebSocket.h"
@ -29,6 +30,7 @@ namespace ix
void setOnConnectionCallback(const OnConnectionCallback& callback); void setOnConnectionCallback(const OnConnectionCallback& callback);
void start(); void start();
void wait();
std::pair<bool, std::string> listen(); std::pair<bool, std::string> listen();
@ -54,6 +56,9 @@ namespace ix
std::atomic<bool> _stop; std::atomic<bool> _stop;
std::thread _thread; std::thread _thread;
std::condition_variable _conditionVariable;
std::mutex _conditionVariableMutex;
const static std::string kDefaultHost; const static std::string kDefaultHost;
// Methods // Methods