Blame server.cpp

f07ad6
646228
#include "utils.h"
f07ad6
#include "protocol.h"
f07ad6
#include "server.h"
f07ad6
#include "connection.h"
f07ad6
f07ad6
f07ad6
f07ad6
Server::Server():
646228
	started(), switching(), socket(), stopRequested(), stopTimeUs() { }
f07ad6
f07ad6
646228
Server::~Server() {
646228
	Lock lock(mutex);
646228
	assert(!started && !socket);
646228
	clean();
646228
}
646228
646228
646228
Protocol& Server::getProtocol() const
646228
	{ assert(socket); return socket->protocol; }
646228
const Address& Server::getLocalAddress() const
646228
	{ assert(socket); return socket->address; }
646228
646228
646228
void Server::clean() {
646228
	started = false;
646228
	socket = nullptr;
646228
	stopRequested = false;
646228
	stopTimeUs = 0;
646228
}
f07ad6
f07ad6
646228
ErrorCode Server::start(Socket *socket) {
f07ad6
	Lock lock(mutex);
646228
	stop();
646228
	
646228
	if (!socket) return ERR_INVALID_ARGS;
646228
	if (switching) return ERR_SERVER_IS_SWITCHING;
f07ad6
	this->socket = socket;
646228
646228
	switching = true;
646228
	ErrorCode errorCode = onStart();
646228
	if (errorCode) clean(); else started = true;
646228
	switching = false;
646228
	
646228
	return errorCode;
f07ad6
}
f07ad6
f07ad6
646228
void Server::stop(ErrorCode errorCode) {
646228
	Lock lock(mutex);
646228
646228
	if (!started || switching) return;
646228
	
646228
	switching = true;
646228
	int unfinichedConnections = getProtocol().stopServer(*this);
646228
	if (!errorCode && unfinichedConnections) errorCode = ERR_SERVER_UNFINISHED_CONNECTIONS;
646228
	onStop(errorCode);
646228
	Socket *socketCopy = socket;
646228
	clean();
646228
	switching = false;
646228
541903
	socketCopy->finalize();
f07ad6
}
f07ad6
646228
646228
void Server::stopReq() {
646228
	Lock lock(mutex);
2499ad
	if (!started || switching || stopRequested) return;
646228
	stopRequested = true;
646228
	getProtocol().stopServerReq(*this);
9bbba5
	onStopRequested();
646228
}
f07ad6
f07ad6
646228
void Server::stopWait(unsigned long long timeoutUs, bool withRequest) {
646228
	std::unique_lock<mutex> uniqlock(mutex);</mutex>
646228
2499ad
	if (!started || switching) return;
646228
	if (withRequest) stopReq();
646228
	unsigned long long timeUs = monotonicTimeUs() + timeoutUs;
646228
	if (stopTimeUs > timeUs)
646228
		{ stopTimeUs = timeUs; stopWaitCondition.notify_all(); }
646228
	
2499ad
	while(started) {
646228
		unsigned long long timeUs = monotonicTimeUs();
646228
		if (timeUs >= stopTimeUs)
646228
			{ stop(ERR_CONNECTION_LOST); break; }
646228
		stopWaitCondition.wait_for(uniqlock, std::chrono::microseconds(stopTimeUs - timeUs));
646228
	}
646228
}
646228
646228
9bbba5
Connection::Handle Server::connect(const Address &remoteAddress)
9bbba5
	{ return onConnect(remoteAddress); }
9bbba5
void Server::disconnect(const Connection::Handle &connection)
9bbba5
	{ onDisconnect(connection); }
9bbba5
9bbba5
646228
ErrorCode Server::onStart()
646228
	{ return ERR_NONE; }
5a39be
void Server::onStopRequested()
9bbba5
	{ }
646228
void Server::onStop(ErrorCode)
f07ad6
	{ }
541903
Connection::Handle Server::onConnect(const Address&)
f07ad6
	{ return nullptr; }
541903
void Server::onDisconnect(const Connection::Handle&)
541903
	{ }