kehuadong

epoll_t类

epoll通常用于单线程读取多个串口的数据

#include <unistd.h>
#include <sys/epoll.h>

#include <mutex>
#include <functional>
#include <map>
using namespace std;

// 这里使用了mutex, map,  防止对象被移除后(移除后有可能就被销毁了),还回调
// ---------------------------------------------------------------------------
class epoll_t
{
private:
	epoll_t();
	epoll_t& operator=(const epoll_t& rhs) = delete;
	epoll_t& operator=(const epoll_t&& rhs) = delete;

public:
	static const epoll_t& self();

public:
	bool add(int fd, function<void(int fd)> callback) const;

	bool remove(int fd) const;

	void wait() const;

private:
	void map_callback(int fd, function<void(int fd)>& callback) const;

	void unmap_callback(int fd) const;

	void on_callback(int fd) const;

private:
	int m_epfd;

	mutable recursive_mutex m_mutex;

	mutable map<int, function<void(int fd)>> m_fd_to_callback;
};

// 构造
// ---------------------------------------------------------------------------
epoll_t::epoll_t()
{
	m_epfd = epoll_create(1024);
}

// 单例
// ---------------------------------------------------------------------------
const epoll_t& epoll_t::self()
{
	static epoll_t instance;
	return instance;
}

// 添加回调
// ---------------------------------------------------------------------------
bool epoll_t::add(int fd, function<void(int fd)> callback) const
{
	map_callback(fd, callback);

	epoll_event ev;
	ev.events = EPOLLIN;
	ev.data.fd = fd;
	return epoll_ctl(m_epfd,  EPOLL_CTL_ADD, fd, &ev) != -1;
}

// 移除回调
// ---------------------------------------------------------------------------
bool epoll_t::remove(int fd) const
{
	unmap_callback(fd);
	return epoll_ctl(m_epfd,  EPOLL_CTL_DEL, fd, NULL) != -1;
}

// 等待数据
// ---------------------------------------------------------------------------
void epoll_t::wait() const
{
	epoll_event ev[8];
	int n = epoll_wait(m_epfd, ev, 8, -1);
	for (int i = 0; i < n; i++)
	{
		on_callback(ev[i].data.fd);
	}
}

// 映射callback
// ---------------------------------------------------------------------------
void epoll_t::map_callback(int fd, function<void(int fd)>& callback) const
{
	unique_lock<recursive_mutex> lock(m_mutex);
	m_fd_to_callback[fd] = callback;
}

// 取消映射callback
// ---------------------------------------------------------------------------
void epoll_t::unmap_callback(int fd) const
{
	unique_lock<recursive_mutex> lock(m_mutex);
	auto it = m_fd_to_callback.find(fd);
	if (it != m_fd_to_callback.end())
	{
		m_fd_to_callback.erase(it);
	}
}

// 回调
// -----------------------------------------------------------------------------------
void epoll_t::on_callback(int fd) const
{
	unique_lock<recursive_mutex> lock(m_mutex);
	auto it = m_fd_to_callback.find(fd);
	if (it != m_fd_to_callback.end())
	{
		it->second(fd);
	}
}

int main()
{
}

 

posted on 2024-01-18 15:09  kehuadong  阅读(6)  评论(0编辑  收藏  举报

导航