Blame protocol.cpp

f07ad6
646228
#include "utils.h"
f07ad6
#include "protocol.h"
f07ad6
#include "server.h"
f07ad6
#include "connection.h"
f07ad6
f07ad6
541903
541903
Socket::Socket(
541903
	Protocol &protocol,
541903
	const Connection::Handle &connection,
541903
	const Server::Handle &server,
541903
	const Address &address
541903
):
541903
	protocol(protocol), connection(connection), server(server), address(address),
541903
	flags(CREATED), prev(), next(), chPrev(), chNext()
f07ad6
{
f07ad6
	prev = protocol.last;
f07ad6
	(prev ? prev->next : protocol.first) = this;
541903
	setChanged(true);
f07ad6
}
f07ad6
f07ad6
541903
Socket::~Socket() {
541903
	setChanged(false);
f07ad6
	(prev ? prev->next : protocol.first) = next;
f07ad6
	(next ? next->prev : protocol.last) = prev;
541903
	prev = next = nullptr;
541903
}
541903
541903
541903
void Socket::setChanged(bool changed) {
541903
	if ((bool)(flags & CHANGED) == changed) return;
541903
	if (changed) {
541903
		flags |= CHANGED;
541903
		chPrev = protocol.chLast;
541903
		(chPrev ? chPrev->chNext : protocol.chFirst) = this;
646228
		protocol.onSocketChanged(this);
541903
	} else {
541903
		flags &= ~CHANGED;
541903
		(chPrev ? chPrev->chNext : protocol.chFirst) = chNext;
541903
		(chNext ? chNext->chPrev : protocol.chLast) = chPrev;
541903
		chPrev = chNext = nullptr;
541903
	}
541903
}
541903
541903
541903
void Socket::setWantRead(bool want) {
541903
	Protocol::Lock lock(protocol.mutex);
541903
	if ((bool)(flags & WANTREAD) == want) return;
541903
	flags = want ? flags | WANTREAD : flags & ~WANTREAD;
541903
	setChanged(true);
541903
}
541903
541903
541903
void Socket::setWantWrite(bool want) {
541903
	Protocol::Lock lock(protocol.mutex);
541903
	if ((bool)(flags & WANTWRITE) == want) return;
541903
	flags = want ? flags | WANTWRITE : flags & ~WANTWRITE;
541903
	setChanged(true);
541903
}
541903
541903
541903
void Socket::finalize() {
541903
	Protocol::Lock lock(protocol.mutex);
541903
	if (flags & REMOVED) return;
541903
	flags |= REMOVED;
541903
	setChanged(true);
f07ad6
}
f07ad6
f07ad6
f07ad6
f07ad6
Protocol::Protocol():
646228
	first(), last(), chFirst(), chLast(),
646228
	started(), switching(), stopping(), stopRequested(), stopTimeUs() { }
f07ad6
f07ad6
646228
Protocol::~Protocol() {
646228
	Lock lockStartStop(mutexStartStop);
646228
	Lock lock(mutex);
646228
	assert(!started);
646228
	clean();
2a209b
}
2a209b
2a209b
646228
ErrorCode Protocol::connectionOpen(const Connection::Handle &connection, Socket *socket)
646228
	{ return connection && socket ? connection->open(socket) : ERR_INVALID_ARGS; }
646228
ErrorCode Protocol::serverStart(const Server::Handle &server, Socket *socket)
646228
	{ return server && socket ? server->start(socket) : ERR_INVALID_ARGS; }
646228
646228
646228
int Protocol::stopServer(Server &server) {
f07ad6
	Lock lock(mutex);
646228
	int count = 0;
646228
	if (started)
646228
		for(Socket *s = socketFirst(); s; s = socketNext(s))
646228
			if (!(socketFlags(s) & Socket::REMOVED) && s->server == &server && s->connection)
646228
				{ s->connection->close(ERR_CONNECTION_LOST); ++count; }
646228
	return count;
f07ad6
}
f07ad6
f07ad6
646228
int Protocol::stopServerReq(Server &server) {
646228
	Lock lock(mutex);
646228
	int count = 0;
646228
	if (started)
646228
		for(Socket *s = socketFirst(); s; s = socketNext(s))
646228
			if (!(socketFlags(s) & Socket::REMOVED) && s->server == &server && s->connection)
646228
				{ s->connection->closeReq(); ++count; }
646228
	return count;
646228
}
646228
646228
646228
void Protocol::clean() {
646228
	assert(!socketFirst());
646228
	while(socketFirst()) delete socketFirst();
646228
	started = false;
646228
	stopping = false;
646228
	stopRequested = false;
646228
	stopTimeUs = 0;
646228
}
646228
646228
646228
ErrorCode Protocol::start() {
646228
	Lock lockStartStop(mutexStartStop);
646228
	Lock lock(mutex);
646228
	stop();
646228
	
646228
	if (switching) return ERR_PROTOCOL_IS_SWITCHING;
646228
	
646228
	switching = true;
646228
	ErrorCode errorCode = onStart();
646228
	if (errorCode) clean(); else started = true;
646228
	switching = false;
646228
	
646228
	return errorCode;
646228
}
646228
646228
646228
void Protocol::stop(ErrorCode errorCode) {
646228
	Lock lockStartStop(mutexStartStop);
646228
	Lock lock(mutex);
646228
	if (!started || switching) return;
646228
	
646228
	switching = true;
646228
	stopping = true;
646228
	int unfinishedConnections = 0;
646228
	for(Socket *s = socketFirst(); s; s = socketNext(s)) {
646228
		if (!(socketFlags(s) & Socket::REMOVED)) {
646228
			if (!s->server && s->connection) {
646228
				s->connection->close(ERR_CONNECTION_LOST);
646228
				++unfinishedConnections;
646228
			} else
646228
			if (s->server && !s->connection) {
646228
				s->server->stop(ERR_SERVER_LISTENING_LOST);
646228
				++unfinishedConnections;
646228
			}
646228
		}
646228
	}
646228
	if (!errorCode && unfinishedConnections) errorCode = ERR_PROTOCOL_UNFINISHED_CONNECTIONS;
646228
	onStop(errorCode);
646228
	clean();
646228
	switching = false;
646228
	
646228
	stopWaitCondition.notify_all();
646228
}
646228
646228
646228
void Protocol::stopReq() {
646228
	Lock lock(mutex);
646228
	if (!started || stopRequested) return;
646228
	stopRequested = true;
646228
	for(Socket *s = socketFirst(); s; s = socketNext(s)) {
646228
		if (!(socketFlags(s) & Socket::REMOVED)) {
646228
			if (!s->server && s->connection)
646228
				s->connection->closeReq();
646228
			else
646228
			if (s->server && !s->connection)
646228
				s->server->stopReq();
646228
		}
646228
	}
646228
}
646228
646228
646228
void Protocol::stopWait(unsigned long long timeoutUs, bool withRequest) {
646228
	std::unique_lock<mutex> uniqlock(mutex);</mutex>
646228
	
646228
	if (!started) return;
646228
	if (withRequest) stopReq();
646228
	unsigned long long timeUs = monotonicTimeUs() + timeoutUs;
646228
	if (stopTimeUs > timeUs)
646228
		{ stopTimeUs = timeUs; stopWaitCondition.notify_all(); }
646228
	
646228
	while(started) {
646228
		unsigned long long timeUs = monotonicTimeUs();
646228
		if (timeUs >= stopTimeUs)
646228
			{ stop(); break; }
646228
		stopWaitCondition.wait_for(uniqlock, std::chrono::microseconds(stopTimeUs - timeUs));
646228
	}
646228
}
646228
646228
646228
ErrorCode Protocol::connect(const Connection::Handle &connection, const Address &address) {
646228
	if (!connection) return ERR_INVALID_ARGS;	
646228
	Lock lock(mutex);
646228
	if (!isFullActive()) return ERR_PROTOCOL_NOT_INITIALIZED;
646228
	return onConnect(connection, address);
646228
}
646228
646228
646228
ErrorCode Protocol::listen(const Server::Handle &server, const Address &address) {
646228
	if (!server) return ERR_INVALID_ARGS;	
646228
	Lock lock(mutex);
646228
	if (!isFullActive()) return ERR_PROTOCOL_NOT_INITIALIZED;
646228
	return onListen(server, address);
646228
}
646228
646228
646228
ErrorCode Protocol::resolve(Address&)
541903
	{ return ERR_ADDRESS_INCORRECT; }
646228
646228
646228
ErrorCode Protocol::onStart()
646228
	{ return ERR_NONE; }
646228
void Protocol::onStop(ErrorCode)
646228
	{ }
646228
void Protocol::onSocketChanged(Socket*) 
646228
	{ }
646228
ErrorCode Protocol::onConnect(const Connection::Handle&, const Address&)
f07ad6
	{ return ERR_CONNECTION_FAILED; }
646228
ErrorCode Protocol::onListen(const Server::Handle&, const Address&)
f07ad6
	{ return ERR_SERVER_LISTENING_FAILED; }
646228
646228