Blame protocol.h

f07ad6
#ifndef PROTOCOL_H
f07ad6
#define PROTOCOL_H
f07ad6
f07ad6
f07ad6
#include <mutex></mutex>
f07ad6
541903
#include "common.h"
f07ad6
#include "address.h"
541903
#include "connection.h"
541903
#include "server.h"
541903
541903
541903
enum : ErrorCode  {
541903
	ERR_PROTOCOL_COMMON = ERR_SERVER,
541903
	ERR_PROTOCOL_NOT_INITIALIZED,
9bbba5
	ERR_PROTOCOL_INITIALIZATION_FAILED,
646228
	ERR_PROTOCOL_UNFINISHED_CONNECTIONS,
646228
	ERR_PROTOCOL_IS_SWITCHING,
541903
};
f07ad6
f07ad6
f07ad6
class Protocol;
f07ad6
f07ad6
f07ad6
class Socket {
f07ad6
public:
541903
	enum : unsigned int {
541903
		CHANGED   = 1 << 0,
541903
		CREATED   = 1 << 1,
541903
		REMOVED   = 1 << 2,
541903
		WANTREAD  = 1 << 3,
541903
		WANTWRITE = 1 << 4, };
541903
	
f07ad6
	Protocol &protocol;
541903
	const Connection::Handle connection;
541903
	const Server::Handle server;
f07ad6
	const Address &address;
f07ad6
	
541903
private:
541903
	friend class Protocol;
541903
	
541903
	// these vars protected by protocol.mutex
541903
	unsigned int flags;
541903
	Socket *prev, *next;
541903
	Socket *chPrev, *chNext;
541903
	
541903
	// protocol.mutex must be already locked
541903
	void setChanged(bool changed);
541903
	
f07ad6
protected:
541903
	// protocol.mutex must be already locked
f07ad6
	Socket(const Socket&) = delete;
541903
	Socket(
541903
		Protocol &protocol,
541903
		const Connection::Handle &connection,
541903
		const Server::Handle &server,
541903
		const Address &address );
541903
	~Socket();
f07ad6
	
9bbba5
	void onConstructionComplete();
9bbba5
	
f07ad6
public:
541903
	// thread-saef methods
541903
	void setWantRead(bool want);
541903
	void setWantWrite(bool want);
541903
	void finalize();
f07ad6
};
f07ad6
f07ad6
541903
class Protocol: public Shared {
f07ad6
public:
98bb38
	typedef THandle<protocol> Handle;</protocol>
541903
	
2499ad
	typedef RecursiveMutex Mutex;
f07ad6
	typedef std::lock_guard<mutex> Lock;</mutex>
f07ad6
	
f07ad6
private:
f07ad6
	friend class Socket;
f07ad6
	Socket *first, *last;
541903
	Socket *chFirst, *chLast;
646228
	bool started;
646228
	bool switching;
646228
	bool stopRequested;
646228
	unsigned long long stopTimeUs;
646228
	std::condition_variable_any stopWaitCondition;
541903
	
646228
protected:
646228
	Mutex mutexStartStop; // using only inside start and stop functions
646228
	Mutex mutex;
646228
	
646228
private:
541903
	inline void socketCheck(Socket *socket, bool mustBeChanged = false) {
541903
		assert(socket);
541903
		assert(&socket->protocol == this);
541903
		assert(!mustBeChanged || (socket->flags & Socket::CHANGED));
541903
	}
541903
	
541903
protected:
541903
	// any class derived from Protocol may access to Socket private members via these methods
541903
	// mutex must be locked before call
646228
	inline bool isStarted() const
646228
		{ return started; }
2499ad
	inline bool isStarting() const
2499ad
		{ return !started && switching; }
646228
	inline bool isStopping() const
2499ad
		{ return started && switching; }
646228
	inline bool isStopRequested() const
646228
		{ return stopRequested; }
646228
	inline bool isActive() const
646228
		{ return isStarted() && !isStopping(); }
646228
	inline bool isFullActive() const
646228
		{ return isActive() && !isStopRequested(); }
646228
	
541903
	inline Socket* socketFirst()
541903
		{ return first; }
541903
	inline Socket* socketNext(Socket *socket)
541903
		{ socketCheck(socket); return socket->next; }
541903
	inline Socket* socketChFirst()
541903
		{ return chFirst; }
541903
	inline Socket* socketChNext(Socket *socket)
541903
		{ socketCheck(socket, true); return socket->chNext; }
f07ad6
	
541903
	inline unsigned int socketFlags(Socket *socket)
541903
		{ socketCheck(socket); return socket->flags; }
9bbba5
	inline unsigned int socketToRemove(Socket *socket)
9bbba5
		{ socketCheck(socket); return socket->flags & Socket::REMOVED; }
646228
	
541903
	inline Socket* socketRemove(Socket *socket)
541903
		{ socketCheck(socket); Socket *next = socket->next; delete socket; return next; }
541903
	inline Socket* socketRemoveChanged(Socket *socket)
541903
		{ socketCheck(socket, true); Socket *chNext = socket->chNext; delete socket; return chNext; }
541903
	inline Socket* socketSetUnchanged(Socket *socket)
541903
		{ socketCheck(socket, true); Socket *chNext = socket->chNext; socket->setChanged(false); return chNext; }
2a209b
	
5a39be
	friend class Server;
5a39be
	friend class Connection;
646228
	ErrorCode connectionOpen(const Connection::Handle &connection, Socket *socket);
646228
	ErrorCode serverStart(const Server::Handle &server, Socket *socket);
9bbba5
	Connection::Handle serverConnect(const Server::Handle &server, const Address &address);
5a39be
	void serverDisconnect(const Server::Handle &server, const Connection::Handle &connection);
646228
	
646228
private:
646228
	// mutex must be locked before call
646228
	// used in start and stop
646228
	void clean();
646228
	
646228
	// functions used by the Server class
646228
	// thread-safe
646228
	friend class Server;
646228
	int stopServer(Server &server);
646228
	int stopServerReq(Server &server);	
541903
f07ad6
public:
541903
	// thread-safe methods
f07ad6
	Protocol();
f07ad6
	virtual ~Protocol();
646228
	
646228
	ErrorCode start();
646228
	void stop(ErrorCode errorCode = ERR_NONE);
646228
	void stopReq();
646228
	void stopWait(unsigned long long timeoutUs, bool withRequest = true);
646228
	
646228
	ErrorCode connect(const Connection::Handle &connection, const Address &address);
646228
	ErrorCode listen(const Server::Handle &server, const Address &address);
646228
	
541903
	virtual ErrorCode resolve(Address &address);
646228
	
646228
protected:
646228
	// mutex must be locked before call
646228
	virtual ErrorCode onStart();
9bbba5
	virtual void onStopRequested();
646228
	virtual void onStop(ErrorCode errorCode);
646228
	virtual void onSocketChanged(Socket *socket);
646228
	virtual ErrorCode onConnect(const Connection::Handle &connection, const Address &address);
646228
	virtual ErrorCode onListen(const Server::Handle &server, const Address &address);
f07ad6
};
f07ad6
f07ad6
f07ad6
#endif