From b569240a55a0df3a78d3cb3e1e673e9347e531c0 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sun, 17 Nov 2013 12:55:45 +0100 Subject: Use epoll --- src/network/poller.cpp | 73 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 4 deletions(-) (limited to 'src/network/poller.cpp') diff --git a/src/network/poller.cpp b/src/network/poller.cpp index e790e60..023fb12 100644 --- a/src/network/poller.cpp +++ b/src/network/poller.cpp @@ -12,6 +12,13 @@ Poller::Poller() #if POLLER == POLL memset(this->fds, 0, sizeof(this->fds)); this->nfds = 0; +#elif POLLER == EPOLL + this->epfd = ::epoll_create1(0); + if (this->epfd == -1) + { + perror("epoll"); + throw std::runtime_error("Could not create epoll instance"); + } #endif } @@ -36,6 +43,17 @@ void Poller::add_socket_handler(std::shared_ptr socket_handler) this->fds[this->nfds].events = POLLIN; this->nfds++; #endif +#if POLLER == EPOLL + struct epoll_event event; + event.data.ptr = socket_handler.get(); + event.events = EPOLLIN; + const int res = ::epoll_ctl(this->epfd, EPOLL_CTL_ADD, socket_handler->get_socket(), &event); + if (res == -1) + { + perror("epoll_ctl"); + throw std::runtime_error("Could not add socket to epoll"); + } +#endif } void Poller::remove_socket_handler(const socket_t socket) @@ -44,6 +62,8 @@ void Poller::remove_socket_handler(const socket_t socket) if (it == this->socket_handlers.end()) throw std::runtime_error("Trying to remove a SocketHandler that is not managed"); this->socket_handlers.erase(it); + +#if POLLER == POLL for (size_t i = 0; i < this->nfds; i++) { if (this->fds[i].fd == socket) @@ -58,9 +78,17 @@ void Poller::remove_socket_handler(const socket_t socket) this->nfds--; } } +#elif POLLER == EPOLL + const int res = ::epoll_ctl(this->epfd, EPOLL_CTL_DEL, socket, nullptr); + if (res == -1) + { + perror("epoll_ctl"); + throw std::runtime_error("Could not remove socket from epoll"); + } +#endif } -void Poller::watch_send_events(const SocketHandler* const socket_handler) +void Poller::watch_send_events(SocketHandler* socket_handler) { #if POLLER == POLL for (size_t i = 0; i <= this->nfds; ++i) @@ -71,11 +99,21 @@ void Poller::watch_send_events(const SocketHandler* const socket_handler) return; } } -#endif throw std::runtime_error("Cannot watch a non-registered socket for send events"); +#elif POLLER == EPOLL + struct epoll_event event; + event.data.ptr = socket_handler; + event.events = EPOLLIN|EPOLLOUT; + const int res = ::epoll_ctl(this->epfd, EPOLL_CTL_MOD, socket_handler->get_socket(), &event); + if (res == -1) + { + perror("epoll_ctl"); + throw std::runtime_error("Could not modify socket flags in epoll"); + } +#endif } -void Poller::stop_watching_send_events(const SocketHandler* const socket_handler) +void Poller::stop_watching_send_events(SocketHandler* socket_handler) { #if POLLER == POLL for (size_t i = 0; i <= this->nfds; ++i) @@ -86,8 +124,18 @@ void Poller::stop_watching_send_events(const SocketHandler* const socket_handler return; } } -#endif throw std::runtime_error("Cannot watch a non-registered socket for send events"); +#elif POLLER == EPOLL + struct epoll_event event; + event.data.ptr = socket_handler; + event.events = EPOLLIN; + const int res = ::epoll_ctl(this->epfd, EPOLL_CTL_MOD, socket_handler->get_socket(), &event); + if (res == -1) + { + perror("epoll_ctl"); + throw std::runtime_error("Could not modify socket flags in epoll"); + } +#endif } bool Poller::poll() @@ -121,6 +169,23 @@ bool Poller::poll() res--; } } +#elif POLLER == EPOLL + static const size_t max_events = 12; + struct epoll_event revents[max_events]; + const int nb_events = epoll_wait(this->epfd, revents, max_events, -1); + if (nb_events == -1) + { + perror("epoll_wait"); + throw std::runtime_error("Epoll_wait failed"); + } + for (int i = 0; i < nb_events; ++i) + { + auto socket_handler = static_cast(revents[i].data.ptr); + if (revents[i].events & EPOLLIN) + socket_handler->on_recv(); + if (revents[i].events & EPOLLOUT) + socket_handler->on_send(); + } #endif return true; } -- cgit v1.2.3