#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