Commit 55917d46 authored by Dan Melnic's avatar Dan Melnic Committed by Facebook GitHub Bot

Add support for TimerFD async recv

Summary: Add support for TimerFD async recv

Reviewed By: kevin-vigor

Differential Revision: D22860507

fbshipit-source-id: e1afc9d72608f5a574413e1230d6665420240af7
parent 8ca7ae74
......@@ -28,6 +28,7 @@ TimerFD::TimerFD(folly::EventBase* eventBase)
TimerFD::TimerFD(folly::EventBase* eventBase, int fd)
: folly::EventHandler(eventBase, NetworkSocket::fromFd(fd)), fd_(fd) {
setEventCallback(this);
if (fd_ > 0) {
registerHandler(folly::EventHandler::READ | folly::EventHandler::PERSIST);
}
......@@ -88,6 +89,18 @@ void TimerFD::handlerReady(uint16_t events) noexcept {
}
}
void TimerFD::eventReadCallback(IoVec* ioVec, int res) {
// reset it
ioVec->timerData_ = 0;
// save it for future use
ioVecPtr_.reset(ioVec);
if (res == sizeof(ioVec->timerData_)) {
DestructorGuard dg(this);
onTimeout();
}
}
int TimerFD::createTimerFd() {
return ::timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
}
......
......@@ -31,7 +31,9 @@
namespace folly {
#ifdef FOLLY_HAVE_TIMERFD
// timerfd wrapper
class TimerFD : public folly::EventHandler, public DelayedDestruction {
class TimerFD : public folly::EventHandler,
public folly::EventReadCallback,
public DelayedDestruction {
public:
explicit TimerFD(folly::EventBase* eventBase);
~TimerFD() override;
......@@ -43,10 +45,42 @@ class TimerFD : public folly::EventHandler, public DelayedDestruction {
// from folly::EventHandler
void handlerReady(uint16_t events) noexcept override;
// from folly::EventReadCallback
folly::EventReadCallback::IoVec* allocateData() override {
auto* ret = ioVecPtr_.release();
return (ret ? ret : new IoVec(this));
}
protected:
void close();
private:
struct IoVec : public folly::EventReadCallback::IoVec {
IoVec() = delete;
~IoVec() override = default;
explicit IoVec(TimerFD* eventFd) {
arg_ = eventFd;
freeFunc_ = IoVec::free;
cbFunc_ = IoVec::cb;
data_.iov_base = &timerData_;
data_.iov_len = sizeof(timerData_);
}
static void free(EventReadCallback::IoVec* ioVec) {
delete ioVec;
}
static void cb(EventReadCallback::IoVec* ioVec, int res) {
reinterpret_cast<TimerFD*>(ioVec->arg_)
->eventReadCallback(reinterpret_cast<IoVec*>(ioVec), res);
}
uint64_t timerData_{0};
};
void eventReadCallback(IoVec* ioVec, int res);
std::unique_ptr<IoVec> ioVecPtr_;
TimerFD(folly::EventBase* eventBase, int fd);
static int createTimerFd();
......
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