Blob Blame Raw
#ifndef PROTOCOL_H
#define PROTOCOL_H


#include <thread>

#include "utils.h"
#include "connection.h"
#include "server.h"



class Protocol {
public:
	enum State {
		STATE_NONE,
		STATE_OPENING,
		STATE_INITIALIZING,
		STATE_OPEN,
		STATE_CLOSE_REQ,
		STATE_CLOSING,
		STATE_CLOSED,
		STATE_FINISHED
	};
	
private:
	friend class Server;
	friend class Connection;
	
	std::thread *thread;
	int epollFd;
	int eventFd;
	
	std::atomic<State> state;
	std::atomic<State> stateWanted;
	ReadProtector stateProtector;

	std::atomic<int> closeWaiters;
	std::atomic<int> finishWaiters;
	std::condition_variable closeCondition;
	
	Connection *connFirst, *connLast;
	Connection::Queue connQueue;

	Server *srvFirst, *srvLast;
	Server::Queue srvQueue;
	
	void wakeup();
	void updateEvents(Connection &connection);
	void initSocket(int sockId);
	
	void wantState(State state);
	
	void threadConnQueue();
	void threadConnEvents(Connection &connection, unsigned int events);
	void threadSrvDisconnect(Server &server, Connection &connection, bool error);
	void threadSrvQueue();
	void threadSrvEvents(Server &server, unsigned int events);
	void threadRun();
	
public:
	Protocol();
	virtual ~Protocol();
	
	bool open();
	void closeReq();
	void close();
	void closeWait(unsigned long long timeoutUs = 0, bool withReq = true);
};


#endif