Blob Blame Raw

#include "protocol.h"
#include "server.h"
#include "connection.h"



Socket::Socket(
	Protocol &protocol,
	const Connection::Handle &connection,
	const Server::Handle &server,
	const Address &address
):
	protocol(protocol), connection(connection), server(server), address(address),
	flags(CREATED), prev(), next(), chPrev(), chNext()
{
	prev = protocol.last;
	(prev ? prev->next : protocol.first) = this;
	setChanged(true);
}


Socket::~Socket() {
	setChanged(false);
	(prev ? prev->next : protocol.first) = next;
	(next ? next->prev : protocol.last) = prev;
	prev = next = nullptr;
}


void Socket::setChanged(bool changed) {
	if ((bool)(flags & CHANGED) == changed) return;
	if (changed) {
		flags |= CHANGED;
		chPrev = protocol.chLast;
		(chPrev ? chPrev->chNext : protocol.chFirst) = this;
		protocol.wakeup();
	} else {
		flags &= ~CHANGED;
		(chPrev ? chPrev->chNext : protocol.chFirst) = chNext;
		(chNext ? chNext->chPrev : protocol.chLast) = chPrev;
		chPrev = chNext = nullptr;
	}
}


void Socket::setWantRead(bool want) {
	Protocol::Lock lock(protocol.mutex);
	if ((bool)(flags & WANTREAD) == want) return;
	flags = want ? flags | WANTREAD : flags & ~WANTREAD;
	setChanged(true);
}


void Socket::setWantWrite(bool want) {
	Protocol::Lock lock(protocol.mutex);
	if ((bool)(flags & WANTWRITE) == want) return;
	flags = want ? flags | WANTWRITE : flags & ~WANTWRITE;
	setChanged(true);
}


void Socket::finalize() {
	Protocol::Lock lock(protocol.mutex);
	if (flags & REMOVED) return;
	flags |= REMOVED;
	setChanged(true);
}



Protocol::Protocol():
	first(), last(), chFirst(), chLast() { }
Protocol::~Protocol()
	{ assert(!first); }


void Protocol::closeAll() {
	Lock lock(mutex);
	while(first) 
		if (first->connection) first->connection->close(); else
			if (first->server) first->server->close(); else
				first->finalize();
}


void Protocol::wakeup() 
	{ }
ErrorCode Protocol::resolve(Address&) 
	{ return ERR_ADDRESS_INCORRECT; }
ErrorCode Protocol::connect(const Connection::Handle&, const Address&)
	{ return ERR_CONNECTION_FAILED; }
ErrorCode Protocol::listen(const Server::Handle&, const Address&)
	{ return ERR_SERVER_LISTENING_FAILED; }