#include <folly/Singleton.h>
#include <folly/experimental/io/IoUringEvent.h>
#include <folly/io/async/EventBaseLocal.h>
#include <folly/io/async/IoUringEventBaseLocal.h>
#if FOLLY_HAS_LIBURING
namespace folly {
namespace {
struct Tag {};
Singleton<EventBaseLocal<std::unique_ptr<IoUringEvent>>, Tag> singleton;
void detach(EventBase* evb) {
auto local = singleton.try_get();
if (!local) {
return;
}
local->erase(*evb);
}
}
IoUringBackend* IoUringEventBaseLocal::try_get(EventBase* evb) {
auto local = singleton.try_get();
if (!local) {
throw std::runtime_error("EventBaseLocal is already destructed");
}
std::unique_ptr<IoUringEvent>* ptr = local->get(*evb);
if (!ptr) {
return nullptr;
}
return &ptr->get()->backend();
}
void IoUringEventBaseLocal::attach(
EventBase* evb, IoUringBackend::Options const& options, bool use_eventfd) {
evb->dcheckIsInEventBaseThread();
evb->runOnDestruction([evb]() { detach(evb); });
auto local = singleton.try_get();
if (!local) {
throw std::runtime_error("EventBaseLocal is already destructed");
}
if (try_get(evb)) {
throw std::runtime_error(
"this event base already has a local io_uring attached");
}
local->emplace(
*evb, std::make_unique<IoUringEvent>(evb, options, use_eventfd));
}
}
#endif