summaryrefslogtreecommitdiff
path: root/louloulibs/network/poller.cpp
diff options
context:
space:
mode:
authorlouiz’ <louiz@louiz.org>2017-03-14 21:45:23 +0100
committerlouiz’ <louiz@louiz.org>2017-03-14 21:45:23 +0100
commit0ab40dc1ab4e689921da54080b135e1d22b1c586 (patch)
tree238ac477aa6b29a8d1e187a8d97ecbcbbbc663ef /louloulibs/network/poller.cpp
parent2d3806152e854ace7533fc3ad34d4ac1c44e9687 (diff)
downloadbiboumi-0ab40dc1ab4e689921da54080b135e1d22b1c586.tar.gz
biboumi-0ab40dc1ab4e689921da54080b135e1d22b1c586.tar.bz2
biboumi-0ab40dc1ab4e689921da54080b135e1d22b1c586.tar.xz
biboumi-0ab40dc1ab4e689921da54080b135e1d22b1c586.zip
Refactoring louloulibs and cmake
Use OBJECT libraries Remove the louloulibs directory Write FOUND variables in the cache
Diffstat (limited to 'louloulibs/network/poller.cpp')
-rw-r--r--louloulibs/network/poller.cpp234
1 files changed, 0 insertions, 234 deletions
diff --git a/louloulibs/network/poller.cpp b/louloulibs/network/poller.cpp
deleted file mode 100644
index 9f5bcfb..0000000
--- a/louloulibs/network/poller.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-#include <network/poller.hpp>
-#include <logger/logger.hpp>
-#include <utils/timed_events.hpp>
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <signal.h>
-#include <unistd.h>
-
-#include <cstring>
-#include <iostream>
-#include <stdexcept>
-
-Poller::Poller()
-{
-#if POLLER == POLL
- this->nfds = 0;
-#elif POLLER == EPOLL
- this->epfd = ::epoll_create1(0);
- if (this->epfd == -1)
- {
- log_error("epoll failed: ", strerror(errno));
- throw std::runtime_error("Could not create epoll instance");
- }
-#endif
-}
-
-Poller::~Poller()
-{
-#if POLLER == EPOLL
- if (this->epfd > 0)
- ::close(this->epfd);
-#endif
-}
-
-void Poller::add_socket_handler(SocketHandler* socket_handler)
-{
- // Don't do anything if the socket is already managed
- const auto it = this->socket_handlers.find(socket_handler->get_socket());
- if (it != this->socket_handlers.end())
- return ;
-
- this->socket_handlers.emplace(socket_handler->get_socket(), socket_handler);
-
- // We always watch all sockets for receive events
-#if POLLER == POLL
- this->fds[this->nfds].fd = socket_handler->get_socket();
- this->fds[this->nfds].events = POLLIN;
- this->nfds++;
-#endif
-#if POLLER == EPOLL
- struct epoll_event event = {EPOLLIN, {socket_handler}};
- const int res = ::epoll_ctl(this->epfd, EPOLL_CTL_ADD, socket_handler->get_socket(), &event);
- if (res == -1)
- {
- log_error("epoll_ctl failed: ", strerror(errno));
- throw std::runtime_error("Could not add socket to epoll");
- }
-#endif
-}
-
-void Poller::remove_socket_handler(const socket_t socket)
-{
- const auto it = this->socket_handlers.find(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)
- {
- // Move all subsequent pollfd by one on the left, erasing the
- // value of the one we remove
- for (size_t j = i; j < this->nfds - 1; ++j)
- {
- this->fds[j].fd = this->fds[j+1].fd;
- this->fds[j].events= this->fds[j+1].events;
- }
- this->nfds--;
- }
- }
-#elif POLLER == EPOLL
- const int res = ::epoll_ctl(this->epfd, EPOLL_CTL_DEL, socket, nullptr);
- if (res == -1)
- {
- log_error("epoll_ctl failed: ", strerror(errno));
- throw std::runtime_error("Could not remove socket from epoll");
- }
-#endif
-}
-
-void Poller::watch_send_events(SocketHandler* socket_handler)
-{
-#if POLLER == POLL
- for (size_t i = 0; i < this->nfds; ++i)
- {
- if (this->fds[i].fd == socket_handler->get_socket())
- {
- this->fds[i].events = POLLIN|POLLOUT;
- return;
- }
- }
- throw std::runtime_error("Cannot watch a non-registered socket for send events");
-#elif POLLER == EPOLL
- struct epoll_event event = {EPOLLIN|EPOLLOUT, {socket_handler}};
- const int res = ::epoll_ctl(this->epfd, EPOLL_CTL_MOD, socket_handler->get_socket(), &event);
- if (res == -1)
- {
- log_error("epoll_ctl failed: ", strerror(errno));
- throw std::runtime_error("Could not modify socket flags in epoll");
- }
-#endif
-}
-
-void Poller::stop_watching_send_events(SocketHandler* socket_handler)
-{
-#if POLLER == POLL
- for (size_t i = 0; i <= this->nfds; ++i)
- {
- if (this->fds[i].fd == socket_handler->get_socket())
- {
- this->fds[i].events = POLLIN;
- return;
- }
- }
- throw std::runtime_error("Cannot watch a non-registered socket for send events");
-#elif POLLER == EPOLL
- struct epoll_event event = {EPOLLIN, {socket_handler}};
- const int res = ::epoll_ctl(this->epfd, EPOLL_CTL_MOD, socket_handler->get_socket(), &event);
- if (res == -1)
- {
- log_error("epoll_ctl failed: ", strerror(errno));
- throw std::runtime_error("Could not modify socket flags in epoll");
- }
-#endif
-}
-
-int Poller::poll(const std::chrono::milliseconds& timeout)
-{
- if (this->socket_handlers.empty() && timeout == utils::no_timeout)
- return -1;
-#if POLLER == POLL
- // Convert our nice timeout into this ugly struct
- struct timespec timeout_ts;
- struct timespec* timeout_tsp;
- if (timeout > 0s)
- {
- auto seconds = std::chrono::duration_cast<std::chrono::seconds>(timeout);
- timeout_ts.tv_sec = seconds.count();
- timeout_ts.tv_nsec = std::chrono::duration_cast<std::chrono::nanoseconds>(timeout - seconds).count();
- timeout_tsp = &timeout_ts;
- }
- else
- timeout_tsp = nullptr;
-
- // Unblock all signals, only during the ppoll call
- sigset_t empty_signal_set;
- sigemptyset(&empty_signal_set);
- int nb_events = ::ppoll(this->fds, this->nfds, timeout_tsp,
- &empty_signal_set);
- if (nb_events < 0)
- {
- if (errno == EINTR)
- return true;
- log_error("poll failed: ", strerror(errno));
- throw std::runtime_error("Poll failed");
- }
- // We cannot possibly have more ready events than the number of fds we are
- // watching
- assert(static_cast<unsigned int>(nb_events) <= this->nfds);
- for (size_t i = 0; i < this->nfds && nb_events != 0; ++i)
- {
- auto socket_handler = this->socket_handlers.at(this->fds[i].fd);
- if (this->fds[i].revents == 0)
- continue;
- else if (this->fds[i].revents & POLLIN && socket_handler->is_connected())
- {
- socket_handler->on_recv();
- nb_events--;
- }
- else if (this->fds[i].revents & POLLOUT && socket_handler->is_connected())
- {
- socket_handler->on_send();
- nb_events--;
- }
- else if (this->fds[i].revents & POLLOUT ||
- this->fds[i].revents & POLLIN)
- {
- socket_handler->connect();
- nb_events--;
- }
- }
- return 1;
-#elif POLLER == EPOLL
- static const size_t max_events = 12;
- struct epoll_event revents[max_events];
- // Unblock all signals, only during the epoll_pwait call
- sigset_t empty_signal_set;
- sigemptyset(&empty_signal_set);
- const int nb_events = ::epoll_pwait(this->epfd, revents, max_events, timeout.count(),
- &empty_signal_set);
- if (nb_events == -1)
- {
- if (errno == EINTR)
- return 0;
- log_error("epoll wait: ", strerror(errno));
- throw std::runtime_error("Epoll_wait failed");
- }
- for (int i = 0; i < nb_events; ++i)
- {
- auto socket_handler = static_cast<SocketHandler*>(revents[i].data.ptr);
- if (revents[i].events & EPOLLIN && socket_handler->is_connected())
- socket_handler->on_recv();
- else if (revents[i].events & EPOLLOUT && socket_handler->is_connected())
- socket_handler->on_send();
- else if (revents[i].events & EPOLLOUT)
- socket_handler->connect();
- }
- return nb_events;
-#endif
-}
-
-size_t Poller::size() const
-{
- return this->socket_handlers.size();
-}
-
-bool Poller::is_managing_socket(const socket_t socket) const
-{
- return (this->socket_handlers.find(socket) != this->socket_handlers.end());
-}