Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef EPOLL_H
- #define EPOLL_H
- extern "C" {
- #include <sys/epoll.h>
- }
- class EpollCb
- {
- public:
- virtual void cb(uint32_t events) = 0;
- virtual int get_fd() = 0;
- };
- class Epoll
- {
- public:
- Epoll();
- Epoll(int timeout);
- Epoll(Epoll const&);
- ~Epoll();
- // throw errno if syscall fails
- void add(EpollCb* ecb, uint32_t events);
- void mod(EpollCb* ecb, uint32_t events);
- void remove(EpollCb* ecb);
- Epoll& operator=(Epoll const&);
- // error-proof
- void dispatch() const;
- void set_timeout(int x);
- int get_timeout() const;
- int get_fd() const;
- private:
- int epoll_;
- int timeout_;
- };
- #endif // EPOLL_H
- #include "epoll.h"
- #include <cerrno>
- extern "C" {
- #include <unistd.h>
- #include <sys/epoll.h>
- }
- #define EVENT_QUEUE_SIZE 128
- Epoll::Epoll(int timeout) : epoll_(epoll_create1(0))
- {
- if (epoll_ == -1)
- throw errno;
- timeout_ = timeout;
- }
- Epoll::Epoll() : Epoll(-1)
- {
- }
- Epoll::Epoll(Epoll const& that) : epoll_(dup(that.get_fd()))
- {
- if (epoll_ == -1)
- throw errno;
- timeout_ = that.get_timeout();
- }
- Epoll& Epoll::operator=(Epoll const& that)
- {
- int new_fd = dup(that.get_fd());
- if (new_fd == -1)
- throw errno;
- close(epoll_);
- epoll_ = new_fd;
- timeout_ = that.get_timeout();
- return *this;
- }
- Epoll::~Epoll()
- {
- close(epoll_);
- }
- void Epoll::set_timeout(int x)
- {
- timeout_ = x;
- }
- int Epoll::get_timeout() const
- {
- return timeout_;
- }
- int Epoll::get_fd() const
- {
- return epoll_;
- }
- void Epoll::add(EpollCb* ecb, uint32_t events)
- {
- struct epoll_event ev = {events, ecb};
- if (epoll_ctl(epoll_, EPOLL_CTL_ADD, ecb->get_fd(), &ev) == -1)
- throw errno;
- }
- void Epoll::mod(EpollCb* ecb, uint32_t events)
- {
- struct epoll_event ev = {events, ecb};
- if (epoll_ctl(epoll_, EPOLL_CTL_MOD, ecb->get_fd(), &ev) == -1)
- throw errno;
- }
- void Epoll::remove(EpollCb *ecb)
- {
- struct epoll_event linux26bug = {};
- if (epoll_ctl(epoll_, EPOLL_CTL_DEL, ecb->get_fd(), &linux26bug) == -1)
- throw errno;
- }
- void Epoll::dispatch() const
- {
- struct epoll_event events[EVENT_QUEUE_SIZE];
- int event_count = epoll_wait(epoll_, events, EVENT_QUEUE_SIZE, timeout_);
- if (event_count < 1)
- return;
- for (int i = 0; i < event_count; ++i) {
- EpollCb* cb = static_cast<EpollCb*>(events[i].data.ptr);
- cb->cb(events[i].events);
- }
- // repeat until queue is empty
- if (event_count == EVENT_QUEUE_SIZE)
- dispatch();
- }
- #include "epoll.h"
- #include <iostream>
- #include <string>
- #include <vector>
- #include <cstdio>
- #include <cerrno>
- extern "C" {
- #include <unistd.h>
- #include <fcntl.h>
- #include <stdlib.h>
- }
- class TerminalWatcher : public EpollCb
- {
- public:
- TerminalWatcher(int fd) : fd_(fd)
- {
- }
- virtual int get_fd()
- {
- return fd_;
- }
- virtual void cb(uint32_t events)
- {
- char buffer[4096];
- std::cout << "events = " << events << std::endl;
- while (read(fd_, buffer, 4096) != -1)
- std::cout << "clearing buffer" << std::endl;
- std::cout << "tell me more..." << std::endl;
- }
- private:
- int const fd_;
- };
- int main()
- {
- fcntl(0, F_SETFL, fcntl(0, F_GETFL)|O_NONBLOCK);
- TerminalWatcher watcher(0);
- Epoll epoll;
- epoll.add(&watcher, EPOLLIN);
- Epoll ecopy(epoll);
- std::cout << "epoll fd = " << epoll.get_fd() << std::endl;
- //while (1) {
- std::cout << "Dispatching..." << std::endl;
- ecopy.dispatch();
- //}
- ecopy.~Epoll();
- // original still works
- epoll.dispatch();
- std::cout << "k thx bye" << std::endl;
- return 0;
- }
Add Comment
Please, Sign In to add comment