Commit a1699e9f authored by Alexander Blom's avatar Alexander Blom Committed by Facebook Github Bot

Make EventBase extend ScheduledExecutor

Summary:
This makes it easier to use EventBase in cases where
classes require ScheduledExecutor instead of Executor. Previously
the client would have to implement a wrapper around EventBase.

Reviewed By: yfeldblum

Differential Revision: D7179869

fbshipit-source-id: 21730a56ed5b71fd731ffd272f9f3752b70d63ce
parent 8579ad47
...@@ -735,6 +735,13 @@ const std::string& EventBase::getName() { ...@@ -735,6 +735,13 @@ const std::string& EventBase::getName() {
return name_; return name_;
} }
void EventBase::scheduleAt(Func&& fn, TimePoint const& timeout) {
auto duration = timeout - now();
timer().scheduleTimeoutFn(
std::move(fn),
std::chrono::duration_cast<std::chrono::milliseconds>(duration));
}
const char* EventBase::getLibeventVersion() { return event_get_version(); } const char* EventBase::getLibeventVersion() { return event_get_version(); }
const char* EventBase::getLibeventMethod() { return event_get_method(); } const char* EventBase::getLibeventMethod() { return event_get_method(); }
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <folly/ScopeGuard.h> #include <folly/ScopeGuard.h>
#include <folly/executors/DrivableExecutor.h> #include <folly/executors/DrivableExecutor.h>
#include <folly/executors/IOExecutor.h> #include <folly/executors/IOExecutor.h>
#include <folly/executors/ScheduledExecutor.h>
#include <folly/executors/SequencedExecutor.h> #include <folly/executors/SequencedExecutor.h>
#include <folly/experimental/ExecutionObserver.h> #include <folly/experimental/ExecutionObserver.h>
#include <folly/io/async/AsyncTimeout.h> #include <folly/io/async/AsyncTimeout.h>
...@@ -130,7 +131,8 @@ class EventBase : private boost::noncopyable, ...@@ -130,7 +131,8 @@ class EventBase : private boost::noncopyable,
public TimeoutManager, public TimeoutManager,
public DrivableExecutor, public DrivableExecutor,
public IOExecutor, public IOExecutor,
public SequencedExecutor { public SequencedExecutor,
public ScheduledExecutor {
public: public:
using Func = folly::Function<void()>; using Func = folly::Function<void()>;
...@@ -628,6 +630,9 @@ class EventBase : private boost::noncopyable, ...@@ -628,6 +630,9 @@ class EventBase : private boost::noncopyable,
loopOnce(); loopOnce();
} }
// Implements the ScheduledExecutor interface
void scheduleAt(Func&& fn, TimePoint const& timeout) override;
/// Returns you a handle which make loop() behave like loopForever() until /// Returns you a handle which make loop() behave like loopForever() until
/// destroyed. loop() will return to its original behavior only when all /// destroyed. loop() will return to its original behavior only when all
/// loop keep-alives are released. /// loop keep-alives are released.
......
...@@ -1073,6 +1073,55 @@ TEST(EventBaseTest, DestroyTimeout) { ...@@ -1073,6 +1073,55 @@ TEST(EventBaseTest, DestroyTimeout) {
T_CHECK_TIMEOUT(start, end, milliseconds(10)); T_CHECK_TIMEOUT(start, end, milliseconds(10));
} }
/**
* Test the scheduled executor impl
*/
TEST(EventBaseTest, ScheduledFn) {
EventBase eb;
TimePoint timestamp1(false);
TimePoint timestamp2(false);
TimePoint timestamp3(false);
eb.schedule(std::bind(&TimePoint::reset, &timestamp1), milliseconds(9));
eb.schedule(std::bind(&TimePoint::reset, &timestamp2), milliseconds(19));
eb.schedule(std::bind(&TimePoint::reset, &timestamp3), milliseconds(39));
TimePoint start;
eb.loop();
TimePoint end;
T_CHECK_TIMEOUT(start, timestamp1, milliseconds(9));
T_CHECK_TIMEOUT(start, timestamp2, milliseconds(19));
T_CHECK_TIMEOUT(start, timestamp3, milliseconds(39));
T_CHECK_TIMEOUT(start, end, milliseconds(39));
}
TEST(EventBaseTest, ScheduledFnAt) {
EventBase eb;
TimePoint timestamp0(false);
TimePoint timestamp1(false);
TimePoint timestamp2(false);
TimePoint timestamp3(false);
eb.scheduleAt(
std::bind(&TimePoint::reset, &timestamp1), eb.now() - milliseconds(5));
eb.scheduleAt(
std::bind(&TimePoint::reset, &timestamp1), eb.now() + milliseconds(9));
eb.scheduleAt(
std::bind(&TimePoint::reset, &timestamp2), eb.now() + milliseconds(19));
eb.scheduleAt(
std::bind(&TimePoint::reset, &timestamp3), eb.now() + milliseconds(39));
TimePoint start;
eb.loop();
TimePoint end;
T_CHECK_TIME_LT(start, timestamp0, milliseconds(0));
T_CHECK_TIMEOUT(start, timestamp1, milliseconds(9));
T_CHECK_TIMEOUT(start, timestamp2, milliseconds(19));
T_CHECK_TIMEOUT(start, timestamp3, milliseconds(39));
T_CHECK_TIMEOUT(start, end, milliseconds(39));
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Test for runInThreadTestFunc() // Test for runInThreadTestFunc()
......
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