Слияние кода завершено, страница обновится автоматически
//
// Created by Administrator on 2015/5/22.
//
#pragma once
#if __cplusplus < 201103L && !defined(_MSC_VER)
#error "should use c++11 to compile this framework!"
#endif
#if defined(_MSC_VER)
#pragma comment(lib, "wsock32.lib")
#endif
#include <vector>
#include <set>
#include <string>
#include <map>
#include <unordered_map>
#include <cassert>
#include <memory>
#if (defined(__WIN32__) && !defined(__CYGWIN__)) || defined(_MSC_VER)
#define __ESVR_WIN32__
typedef unsigned int socket_t;
typedef int socklen_t;
const socket_t socket_t_invalid = 1;
const socket_t sock_t_invalid = 1;
#define ERRNO (WSAGetLastError())
#define NEEDBLOCK WSAEWOULDBLOCK
#include <winsock.h>
#elif defined(__linux__) || defined(__CYGWIN__) || defined(__unix__) || defined(__CYGWIN32__) || defined(__APPLE__)
#define __ESVR_LINUX__
typedef int socket_t;
#include <sys/socket.h>
#include <errno.h>
const socket_t socket_t_invalid = -1;
const socket_t sock_t_invalid = -1;
#define ERRNO (errno)
#define NEEDBLOCK EAGAIN
#endif
#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__MINGW32__)
#define CHECK_RESULT __attribute__ ((unused))
#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
#define CHECK_RESULT _Check_return_
#define noexcept
#else
#define CHECK_RESULT
#define noexcept
#endif
#define HAVE_SELECT #select 肯定有的
#if defined(__linux__)
#include <linux/version.h>
#define HAVE_POLL //老的linux内核用poll
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
#define HAVE_EPOLL //新的linux内核用epoll
#endif
#endif
#if defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__APPLE__)
#define HAVE_POLL //cygwin&mac os支持poll
#endif
#define DEF_EMPTY_EVENT(NAME, TYPE) class NAME : public Event {\
private:\
public:\
NAME(){}\
NAME(const NAME& t){}\
std::string to_string() const {return #NAME;}\
static ES_EVENT type(){return TYPE;}\
static std::string type_str(){return get_event_str(TYPE);}\
}
#define DEF_FD_EVENT(NAME, TYPE) class NAME : public Event {\
private:\
socket_t m_fd = socket_t_invalid;\
public:\
NAME(){} \
NAME(socket_t fd) : m_fd(fd){}\
NAME(const NAME& t) {m_fd = t.m_fd;}\
socket_t fd() const {return m_fd;}\
std::string to_string() const {return #NAME;}\
static ES_EVENT type(){return TYPE;}\
static std::string type_str(){return get_event_str(TYPE);}\
}
#define DEF_FD_BUFFER_EVENT(NAME, TYPE) class NAME : public Event {\
private:\
socket_t m_fd = sock_t_invalid;\
const char* m_data = NULL;\
size_t m_len = 0;\
public:\
NAME(){}\
NAME(socket_t fd, const char* data, size_t len) : m_fd(fd), m_data(data), m_len(len){}\
NAME(const NAME& t){m_fd = t.m_fd; m_data = t.m_data; m_len = t.m_len;}\
socket_t fd() const {return m_fd;}\
std::string to_string() const {return #NAME;}\
size_t len() const {return m_len;}\
const char* data() const { return m_data;}\
static ES_EVENT type(){return TYPE;}\
static std::string type_str(){return get_event_str(TYPE);}\
};
namespace esvr
{
typedef enum
{
ES_DEFAULT = 0x0000, //no event
ES_READ = 0x0001, //read event
ES_WRITE = 0x0002, //write event
ES_CONNECTED = 0x0004, //connect event
ES_CLOSED = 0x0008, //closed event
ES_IDLE = 0x0010, //server idle event
ES_MODIFIED = 0x0020, //file modify event
} ES_EVENT;
extern std::string get_event_str(ES_EVENT event);
template <typename T>
class Creator
{
public:
static T* create()
{
return new T;
}
static void destroy(T* &v)
{
delete v;
v = NULL;
}
};
template <typename T>
class AutoReleaseSingleton
{
private:
T* m_handler;
private:
AutoReleaseSingleton(const AutoReleaseSingleton&): m_handler(NULL){}
AutoReleaseSingleton& operator = (const AutoReleaseSingleton&){return *this;}
public:
AutoReleaseSingleton(T* handler=NULL) : m_handler(handler) {}
void AllocInst()
{
if(!m_handler) m_handler = T::create();
}
~AutoReleaseSingleton()
{
if(m_handler) T::destroy(m_handler);
m_handler = NULL;
}
T* data() noexcept
{
AllocInst();
return m_handler;
}
T* operator& () noexcept
{
AllocInst();
return m_handler;
}
T& operator* () noexcept
{
AllocInst();
return *m_handler;
}
};
template<typename T>
class LockFreeQueue;
class BlockList;
class IOManager
{
public:
static IOManager& instance()
{
static IOManager manager;
return manager;
}
static IOManager& get_instance()
{
return instance();
}
public:
void start(socket_t server_fd, int millisecond=100)
{
m_serverfd = server_fd;
m_wait_millisecond = millisecond;
m_start = true;
m_active_clients.clear();
before_start();
main_loop();
}
int send(socket_t /*cli_fd*/, const char* /*buffer*/, const size_t /*size*/);
void stop();
virtual void before_start();
virtual void before_stop();
virtual void after_stop();
virtual void before_loop_once();
virtual void after_loop_once();
virtual void on_idle();
//thread safe.
void force_close(socket_t fd);
protected:
void main_loop();
void readable_buffer(socket_t fd, char* & buffer, size_t& readable_len);
void writable_buffer(socket_t fd, char* & buffer, size_t& writable_len);
void increase_readable(socket_t fd, size_t len);
void decrease_readable(socket_t fd, size_t len);
void new_fd(socket_t fd);
void delete_fd(socket_t fd);
LockFreeQueue<socket_t> * get_to_close_queue();
private:
volatile bool m_start = false;
socket_t m_serverfd = socket_t_invalid;
int m_wait_millisecond = 0;
std::string m_io_type = "None";
std::unordered_map<socket_t, BlockList*> m_active_clients;
};
class Event
{
public:
Event() = default;
ES_EVENT type(){return ES_DEFAULT;}
Event(const Event&) = delete;
};
DEF_FD_EVENT(ConnectedEvent, ES_CONNECTED);
DEF_FD_EVENT(ClosedEvent, ES_CLOSED);
DEF_FD_BUFFER_EVENT(ReadEvent, ES_READ);
DEF_FD_BUFFER_EVENT(WriteEvent, ES_WRITE);
DEF_EMPTY_EVENT(IdleEvent, ES_IDLE);
template<typename T>
class EventListener
{
private:
int m_listen_flag{0};
public:
virtual void on_event(const T*){}
virtual ~EventListener(){}
EventListener(){m_listen_flag |= (int) T::type();}
};
class EventBus
{
public:
typedef std::map<ES_EVENT, std::set<void*>> listener_map_t;
static EventBus& get_instance()
{
static EventBus event_bus;
return event_bus;
}
static EventBus& instance()
{
return get_instance();
}
template<typename T>
void add_handler(EventListener<T>* listener)
{
auto it = m_listeners.find(T::type());
if(it == m_listeners.end())
{
m_listeners[T::type()] = std::set<void*>();
it = m_listeners.find(T::type());
}
it->second.insert(listener);
}
template<typename T>
void remove_handler(EventListener<T>* listener)
{
auto it = m_listeners.find(T::type());
if(it != m_listeners.end())
{
it->second.erase(listener);
}
}
template<typename T>
void fire_event(const T* event);
protected:
template<typename T>
void dispatch_event(const T* event, bool free=false);
private:
listener_map_t m_listeners;
};
};
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )