Skip to content

Instantly share code, notes, and snippets.

@303248153
Created July 26, 2019 01:17
Show Gist options
  • Save 303248153/61135ddf6974774bbdfceaa3b27e4e67 to your computer and use it in GitHub Desktop.
Save 303248153/61135ddf6974774bbdfceaa3b27e4e67 to your computer and use it in GitHub Desktop.
--- a/include/seastar/core/internal/pollable_fd.hh
+++ b/include/seastar/core/internal/pollable_fd.hh
@@ -57,6 +57,7 @@ class pollable_fd_state {
int events_requested = 0; // wanted by pollin/pollout promises
int events_epoll = 0; // installed in epoll
int events_known = 0; // returned from epoll
+ bool is_acceptor = false; // put acceptor to disinct epoll
promise<> pollin;
promise<> pollout;
friend class reactor;
diff --git a/src/core/reactor.cc b/src/core/reactor.cc
index f57ca0c9..83acfbce 100644
--- a/src/core/reactor.cc
+++ b/src/core/reactor.cc
@@ -667,6 +667,8 @@ class reactor_backend_epoll : public reactor_backend {
bool _timer_enabled = false;
private:
file_desc _epollfd;
+ file_desc _epollfd_for_acceptor;
+ file_desc& get_epollfd(pollable_fd_state& fd);
future<> get_epoll_future(pollable_fd_state& fd,
promise<> pollable_fd_state::* pr, int event);
void complete_epoll_event(pollable_fd_state& fd,
@@ -978,8 +980,10 @@ class reactor_backend_aio : public reactor_backend {
}
};
-reactor_backend_epoll::reactor_backend_epoll(reactor* r)
- : _r(r), _epollfd(file_desc::epoll_create(EPOLL_CLOEXEC)) {
+reactor_backend_epoll::reactor_backend_epoll(reactor* r) :
+ _r(r),
+ _epollfd(file_desc::epoll_create(EPOLL_CLOEXEC)),
+ _epollfd_for_acceptor(file_desc::epoll_create(EPOLL_CLOEXEC)) {
::epoll_event event;
event.events = EPOLLIN;
event.data.ptr = nullptr;
@@ -1800,6 +1804,13 @@ void reactor::configure(boost::program_options::variables_map vm) {
aio_nowait_supported = vm["linux-aio-nowait"].as<bool>();
}
+file_desc& reactor_backend_epoll::get_epollfd(pollable_fd_state& fd) {
+ if (fd.is_acceptor) {
+ return _epollfd_for_acceptor;
+ }
+ return _epollfd;
+}
+
future<> reactor_backend_epoll::get_epoll_future(pollable_fd_state& pfd,
promise<> pollable_fd_state::*pr, int event) {
if (pfd.events_known & event) {
@@ -1814,7 +1825,7 @@ future<> reactor_backend_epoll::get_epoll_future(pollable_fd_state& pfd,
::epoll_event eevt;
eevt.events = pfd.events_epoll;
eevt.data.ptr = &pfd;
- int r = ::epoll_ctl(_epollfd.get(), ctl, pfd.fd.get(), &eevt);
+ int r = ::epoll_ctl(get_epollfd(pfd).get(), ctl, pfd.fd.get(), &eevt);
assert(r == 0);
engine().start_epoll();
}
@@ -1836,7 +1847,7 @@ future<> reactor_backend_epoll::readable_or_writeable(pollable_fd_state& fd) {
void reactor_backend_epoll::forget(pollable_fd_state& fd) {
if (fd.events_epoll) {
- ::epoll_ctl(_epollfd.get(), EPOLL_CTL_DEL, fd.fd.get(), nullptr);
+ ::epoll_ctl(get_epollfd(fd).get(), EPOLL_CTL_DEL, fd.fd.get(), nullptr);
}
}
@@ -1856,7 +1867,9 @@ reactor::posix_listen(socket_address sa, listen_options opts) {
throw std::system_error(s.code(), fmt::format("posix_listen failed for address {}", sa));
}
- return pollable_fd(std::move(fd));
+ pollable_fd pfd(std::move(fd));
+ pfd._s->is_acceptor = true;
+ return pfd;
}
bool
@@ -4518,8 +4531,23 @@ reactor::poller::~poller() {
bool
reactor_backend_epoll::wait_and_process(int timeout, const sigset_t* active_sigmask) {
thread_local static std::chrono::steady_clock::time_point last_epoll_flushed = std::chrono::steady_clock::now();
+ thread_local std::size_t count = 0;
std::array<epoll_event, 128> eevt;
- int nr = ::epoll_pwait(_epollfd.get(), eevt.data(), eevt.size(), timeout, active_sigmask);
+ file_desc* epoll_fd_ptr;
+ int timeout_val;
+ if (++count % 2 == 0) {
+ epoll_fd_ptr = &_epollfd_for_acceptor;
+ timeout_val = 0;
+ } else {
+ epoll_fd_ptr = &_epollfd;
+ timeout_val = timeout;
+ }
+ int nr = ::epoll_pwait(epoll_fd_ptr->get(), eevt.data(), eevt.size(), timeout_val, active_sigmask);
+ if (nr == 0 && epoll_fd_ptr == &_epollfd_for_acceptor) {
+ epoll_fd_ptr = &_epollfd;
+ timeout_val = timeout;
+ nr = ::epoll_pwait(epoll_fd_ptr->get(), eevt.data(), eevt.size(), timeout_val, active_sigmask);
+ }
if (nr == -1 && errno == EINTR) {
return false; // gdb can cause this
}
@@ -4557,7 +4585,7 @@ reactor_backend_epoll::wait_and_process(int timeout, const sigset_t* active_sigm
pfd->events_epoll &= ~events_to_remove;
evt.events = pfd->events_epoll;
auto op = evt.events ? EPOLL_CTL_MOD : EPOLL_CTL_DEL;
- ::epoll_ctl(_epollfd.get(), op, pfd->fd.get(), &evt);
+ ::epoll_ctl(epoll_fd_ptr->get(), op, pfd->fd.get(), &evt);
}
}
return nr;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment