Blob Blame Raw
#ifndef SERVER_H
#define SERVER_H


#include "connection.h"


class Server: public Root {
	enum State: int {
		STATE_NONE,
		STATE_OPENING,
		STATE_INITIALIZING,
		STATE_RESOLVING,
		STATE_OPEN,
		STATE_CLOSE_REQ,
		STATE_CLOSING_CONNECTIONS,
		STATE_CLOSING,
		STATE_CLOSED,
		STATE_FINISHED
	};
	
private:
	friend class Protocol;
	
	std::atomic<State> state;
	std::atomic<State> stateWanted;
	ReadProtector stateProtector;
	std::atomic<bool> enqueued;
	std::atomic<bool> error;
	
	std::atomic<int> closeWaiters;
	std::atomic<int> finishWaiters;
	std::condition_variable closeCondition;

	unsigned char address[MAX_ADDR_SIZE];
	size_t addressSize;
	
	Protocol *protocol;
	Server *prev, *next;
	Server *queueNext;
	Connection *connFirst, *connLast;
	int sockId;
	State stateLocal;
	
	void wantState(State state, bool error);
	
public:
	typedef      QueueMISO<Server, &Server::queueNext> Queue;
	friend class QueueMISO<Server, &Server::queueNext>;
	friend class ChainFuncs<Server, &Server::queueNext>;
	
public:
	Server();
	~Server();
	
	bool open(Protocol &protocol, void *address, size_t addressSize);
	void closeReq();
	void close(bool error);
	void closeWait(unsigned long long timeoutUs = 0, bool withReq = true);
	
protected:
	virtual void onOpeningError();
	virtual void onOpen();
	virtual Connection* onConnect(const void *address, size_t addressSize);
	virtual void onDisconnect(Connection *connection, bool error);
	virtual void onCloseReqested();
	virtual void onClose(bool error);
};


#endif