Guest User

Untitled

a guest
Oct 20th, 2017
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.57 KB | None | 0 0
  1. #ifndef EPOLL_H
  2. #define EPOLL_H
  3.  
  4. extern "C" {
  5. #include <sys/epoll.h>
  6. }
  7.  
  8. class EpollCb
  9. {
  10. public:
  11. virtual void cb(uint32_t events) = 0;
  12. virtual int get_fd() = 0;
  13. };
  14.  
  15. class Epoll
  16. {
  17. public:
  18. Epoll();
  19. Epoll(int timeout);
  20. Epoll(Epoll const&);
  21. ~Epoll();
  22.  
  23. // throw errno if syscall fails
  24. void add(EpollCb* ecb, uint32_t events);
  25. void mod(EpollCb* ecb, uint32_t events);
  26. void remove(EpollCb* ecb);
  27. Epoll& operator=(Epoll const&);
  28.  
  29. // error-proof
  30. void dispatch() const;
  31. void set_timeout(int x);
  32. int get_timeout() const;
  33. int get_fd() const;
  34.  
  35. private:
  36. int epoll_;
  37. int timeout_;
  38. };
  39.  
  40. #endif // EPOLL_H
  41.  
  42. #include "epoll.h"
  43. #include <cerrno>
  44.  
  45. extern "C" {
  46. #include <unistd.h>
  47. #include <sys/epoll.h>
  48. }
  49.  
  50. #define EVENT_QUEUE_SIZE 128
  51.  
  52. Epoll::Epoll(int timeout) : epoll_(epoll_create1(0))
  53. {
  54. if (epoll_ == -1)
  55. throw errno;
  56.  
  57. timeout_ = timeout;
  58. }
  59.  
  60. Epoll::Epoll() : Epoll(-1)
  61. {
  62. }
  63.  
  64. Epoll::Epoll(Epoll const& that) : epoll_(dup(that.get_fd()))
  65. {
  66. if (epoll_ == -1)
  67. throw errno;
  68.  
  69. timeout_ = that.get_timeout();
  70. }
  71.  
  72. Epoll& Epoll::operator=(Epoll const& that)
  73. {
  74. int new_fd = dup(that.get_fd());
  75. if (new_fd == -1)
  76. throw errno;
  77.  
  78. close(epoll_);
  79. epoll_ = new_fd;
  80. timeout_ = that.get_timeout();
  81.  
  82. return *this;
  83. }
  84.  
  85. Epoll::~Epoll()
  86. {
  87. close(epoll_);
  88. }
  89.  
  90. void Epoll::set_timeout(int x)
  91. {
  92. timeout_ = x;
  93. }
  94.  
  95. int Epoll::get_timeout() const
  96. {
  97. return timeout_;
  98. }
  99.  
  100. int Epoll::get_fd() const
  101. {
  102. return epoll_;
  103. }
  104.  
  105. void Epoll::add(EpollCb* ecb, uint32_t events)
  106. {
  107. struct epoll_event ev = {events, ecb};
  108.  
  109. if (epoll_ctl(epoll_, EPOLL_CTL_ADD, ecb->get_fd(), &ev) == -1)
  110. throw errno;
  111. }
  112.  
  113. void Epoll::mod(EpollCb* ecb, uint32_t events)
  114. {
  115. struct epoll_event ev = {events, ecb};
  116.  
  117. if (epoll_ctl(epoll_, EPOLL_CTL_MOD, ecb->get_fd(), &ev) == -1)
  118. throw errno;
  119. }
  120.  
  121. void Epoll::remove(EpollCb *ecb)
  122. {
  123. struct epoll_event linux26bug = {};
  124.  
  125. if (epoll_ctl(epoll_, EPOLL_CTL_DEL, ecb->get_fd(), &linux26bug) == -1)
  126. throw errno;
  127. }
  128.  
  129. void Epoll::dispatch() const
  130. {
  131. struct epoll_event events[EVENT_QUEUE_SIZE];
  132. int event_count = epoll_wait(epoll_, events, EVENT_QUEUE_SIZE, timeout_);
  133.  
  134. if (event_count < 1)
  135. return;
  136.  
  137. for (int i = 0; i < event_count; ++i) {
  138. EpollCb* cb = static_cast<EpollCb*>(events[i].data.ptr);
  139. cb->cb(events[i].events);
  140. }
  141.  
  142. // repeat until queue is empty
  143. if (event_count == EVENT_QUEUE_SIZE)
  144. dispatch();
  145. }
  146.  
  147. #include "epoll.h"
  148. #include <iostream>
  149. #include <string>
  150. #include <vector>
  151. #include <cstdio>
  152. #include <cerrno>
  153.  
  154. extern "C" {
  155. #include <unistd.h>
  156. #include <fcntl.h>
  157. #include <stdlib.h>
  158. }
  159.  
  160. class TerminalWatcher : public EpollCb
  161. {
  162. public:
  163. TerminalWatcher(int fd) : fd_(fd)
  164. {
  165. }
  166.  
  167. virtual int get_fd()
  168. {
  169. return fd_;
  170. }
  171.  
  172. virtual void cb(uint32_t events)
  173. {
  174. char buffer[4096];
  175.  
  176. std::cout << "events = " << events << std::endl;
  177.  
  178. while (read(fd_, buffer, 4096) != -1)
  179. std::cout << "clearing buffer" << std::endl;
  180.  
  181. std::cout << "tell me more..." << std::endl;
  182. }
  183.  
  184. private:
  185. int const fd_;
  186. };
  187.  
  188. int main()
  189. {
  190. fcntl(0, F_SETFL, fcntl(0, F_GETFL)|O_NONBLOCK);
  191.  
  192. TerminalWatcher watcher(0);
  193. Epoll epoll;
  194. epoll.add(&watcher, EPOLLIN);
  195.  
  196. Epoll ecopy(epoll);
  197.  
  198. std::cout << "epoll fd = " << epoll.get_fd() << std::endl;
  199.  
  200. //while (1) {
  201. std::cout << "Dispatching..." << std::endl;
  202. ecopy.dispatch();
  203. //}
  204.  
  205. ecopy.~Epoll();
  206.  
  207. // original still works
  208. epoll.dispatch();
  209.  
  210. std::cout << "k thx bye" << std::endl;
  211.  
  212. return 0;
  213. }
Add Comment
Please, Sign In to add comment