Blob Blame Raw
#ifndef SERVER_H
#define SERVER_H


#include <mutex>

#include "common.h"
#include "address.h"


class Socket;
class Protocol;
class Connection;


enum : ErrorCode  {
	ERR_SERVER_COMMON = ERR_SERVER,
	ERR_SERVER_LISTENING_FAILED,
	ERR_SERVER_UNFINISHED_CONNECTIONS,
	ERR_SERVER_LISTENING_LOST,
	ERR_SERVER_IS_SWITCHING,
};


class Server: public Shared {
public:
	typedef THandle<Server> Handle;
	
	typedef RecursiveMutex Mutex;
	typedef std::lock_guard<Mutex> Lock;
	
private:
	Mutex mutex;
	bool started;
	bool switching;
	Socket *socket;
	
	bool stopRequested;
	unsigned long long stopTimeUs;
	std::condition_variable_any stopWaitCondition;
	
	// mutex must be locked before call
	// used in open and close
	void clean();
	
	friend class Protocol;
	ErrorCode start(Socket *socket);
	THandle<Connection> connect(const Address &remoteAddress);
	void disconnect(const THandle<Connection> &connection);
	
public:
	Server();
	~Server();
	
	void stop(ErrorCode errorCode = ERR_NONE);
	void stopReq();
	void stopWait(unsigned long long timeoutUs, bool withRequest = true);
	
protected:
	// mutex must be locked before call of all following methods
	Protocol& getProtocol() const;
	const Address& getLocalAddress() const;
	
	virtual ErrorCode onStart();
	virtual void onStopRequested();
	virtual void onStop(ErrorCode errorCode);
	virtual THandle<Connection> onConnect(const Address &remoteAddress);
	virtual void onDisconnect(const THandle<Connection> &connection);
};


#endif