Blame socket.h

b42f0a
#ifndef SOCKET_H
b42f0a
#define SOCKET_H
b42f0a
b42f0a
b42f0a
#include <cassert></cassert>
b42f0a
b42f0a
#include <atomic></atomic>
b42f0a
#include <condition_variable></condition_variable>
b42f0a
b42f0a
#include "utils.h"
b42f0a
b42f0a
b42f0a
#define MAX_ADDR_SIZE 256
b42f0a
b42f0a
b42f0a
b42f0a
enum State: int {
b42f0a
	STATE_NONE,
b42f0a
	STATE_OPENING,
b42f0a
	STATE_INITIALIZING,
b42f0a
	STATE_RESOLVING,
b42f0a
	STATE_CONNECTING,
b42f0a
	STATE_OPEN,
b42f0a
	STATE_CLOSE_REQ,
b42f0a
	STATE_CLOSING_CONNECTIONS,
b42f0a
	STATE_CLOSING,
b42f0a
	STATE_CLOSED,
b42f0a
	STATE_FINISHED,
b42f0a
	STATE_DESTROYED
b42f0a
};
b42f0a
b42f0a
b42f0a
class Protocol;
b42f0a
class Connection;
b42f0a
class Server;
b42f0a
b42f0a
b42f0a
class Socket {
b42f0a
private:
b42f0a
	friend class Protocol;
b42f0a
	friend class Connection;
b42f0a
	friend class Server;
b42f0a
	
b42f0a
	std::atomic<state> state;</state>
b42f0a
	std::atomic<state> stateWanted;</state>
b42f0a
	ReadProtector stateProtector;
b42f0a
	std::atomic<bool> enqueued;</bool>
b42f0a
	std::atomic<bool> error;</bool>
b42f0a
	
b42f0a
	std::atomic<int> closeWaiters;</int>
b42f0a
	std::atomic<int> finishWaiters;</int>
b42f0a
	std::condition_variable closeCondition;
b42f0a
	
b42f0a
	unsigned char address[MAX_ADDR_SIZE];
b42f0a
	size_t addressSize;
b42f0a
	
b42f0a
	Protocol *protocol;
b42f0a
	Socket *prev, *next;
b42f0a
	Socket *queueNext;
b42f0a
	int sockId;
b42f0a
	State stateLocal;
b42f0a
	
b42f0a
	std::atomic<unsigned int=""> events;</unsigned>
b42f0a
	
b42f0a
	struct OpenLock {
b42f0a
		Socket &socket;
b42f0a
		const bool success;
b42f0a
		OpenLock(Socket &socket, Protocol &protocol, void *address, size_t addressSize):
b42f0a
			socket(socket), success(socket.openBegin(protocol, address, addressSize)) { }
b42f0a
		~OpenLock()
b42f0a
			{ if (success) socket.openEnd(); }
b42f0a
	};
b42f0a
	
b42f0a
	bool openBegin(Protocol &protocol, void *address, size_t addressSize);
b42f0a
	void openEnd();
b42f0a
	
b42f0a
	void initSocket(int sockId);
b42f0a
	void enqueue();
b42f0a
	void updateEvents(bool wantRead, bool wantWrite);
b42f0a
	void wantState(State state, bool error);
b42f0a
	
b42f0a
	void destroy();
b42f0a
	
b42f0a
public:
b42f0a
	typedef      QueueMISO<socket, &socket::queuenext=""> Queue;</socket,>
b42f0a
	friend class QueueMISO<socket, &socket::queuenext="">;</socket,>
b42f0a
	friend class ChainFuncs<socket, &socket::queuenext="">;</socket,>
b42f0a
	
b42f0a
public:
b42f0a
	Socket();
b42f0a
	virtual ~Socket();
b42f0a
	
b42f0a
	void closeReq();
b42f0a
	void close(bool error);
b42f0a
	void closeWait(unsigned long long timeoutUs = 0, bool withReq = true, bool error = true);
b42f0a
	
b42f0a
private:
b42f0a
	virtual void handleState() = 0;
b42f0a
	virtual void handleEvents(unsigned int events) = 0;
b42f0a
	
b42f0a
protected:
b42f0a
	virtual void onOpeningError();
b42f0a
	virtual void onOpen(const void *address, size_t addressSize);
b42f0a
	virtual void onCloseReqested();
b42f0a
	virtual void onClose(bool error);
b42f0a
};
b42f0a
b42f0a
b42f0a
#endif