Commit 536086dc authored by Dan Melnic's avatar Dan Melnic Committed by Facebook GitHub Bot

Delay registration of the timer and signal fds until running the loop first time

Summary:
Delay registration of the timer and signal fds until running the loop first time
On some Linux kernel versions, io_uring will remove any fd registrations on thread exit. So creating the backend in a thread that exits later will cause us not to receive timer and signal fd events.

Reviewed By: kevin-vigor

Differential Revision: D26200805

fbshipit-source-id: dc3025964deb3cf87bf3e5a27141abcdb8698caf
parent 20549953
......@@ -448,11 +448,7 @@ IoUringBackend::IoUringBackend(Options options)
fdRegistry_.init();
}
// add the timer fd
if (!addTimerFd() || !addSignalFds()) {
cleanup();
throw NotAvailable("io_uring_submit error");
}
// delay adding the timer and signal fds until running the loop first time
}
IoUringBackend::~IoUringBackend() {
......@@ -828,6 +824,14 @@ size_t IoUringBackend::processActiveEvents() {
}
int IoUringBackend::eb_event_base_loop(int flags) {
if (FOLLY_UNLIKELY(registerDefaultFds_)) {
registerDefaultFds_ = false;
if (!addTimerFd() || !addSignalFds()) {
cleanup();
throw NotAvailable("io_uring_submit error");
}
}
// schedule the timers
bool done = false;
auto waitForEvents = (flags & EVLOOP_NONBLOCK) ? WaitForEventsMode::DONT_WAIT
......
......@@ -796,6 +796,8 @@ class IoUringBackend : public EventBaseBackendBase {
// poll callback to be invoked if POLL_CQ flag is set
// every time we poll for a CQE
CQPollLoopCallback cqPollLoopCallback_;
bool registerDefaultFds_{true};
};
using PollIoBackend = IoUringBackend;
......
......@@ -554,10 +554,10 @@ TEST(IoUringBackend, RegisteredFds) {
CHECK(!record);
std::vector<folly::IoUringBackend::FdRegistrationRecord*> records;
// we use kBackendCapacity -1 since we can have the timerFd
// already using one fd
records.reserve(kBackendCapacity - 1);
for (size_t i = 0; i < kBackendCapacity - 1; i++) {
// we use kBackendCapacity since the timerFd
// allocates it only on the first loop
records.reserve(kBackendCapacity);
for (size_t i = 0; i < kBackendCapacity; i++) {
record = backendReg->registerFd(eventFd);
CHECK(record);
records.emplace_back(record);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment