#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