Commit 11329181 authored by Hans Fugal's avatar Hans Fugal Committed by Dave Watson

HHWheelTimer::scheduleTimeoutFn

Summary:
cpp11ify

I'm gonna use this for Wangle timeouts.

Test Plan:
new unit test
_bin/folly/io/async/test/HHWheelTimerTest

Reviewed By: jsedgwick@fb.com

Subscribers: trunkagent, exa, njormrod, folly-diffs@

FB internal diff: D1720014

Tasks: 5002969

Signature: t1:1720014:1417732753:ddcad431b6c305c9ba27f6b9e3454ab158c13f4b
parent 4399c9e4
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <folly/io/async/DelayedDestruction.h> #include <folly/io/async/DelayedDestruction.h>
#include <boost/intrusive/list.hpp> #include <boost/intrusive/list.hpp>
#include <glog/logging.h>
#include <chrono> #include <chrono>
#include <cstddef> #include <cstddef>
...@@ -176,6 +177,24 @@ class HHWheelTimer : private folly::AsyncTimeout, ...@@ -176,6 +177,24 @@ class HHWheelTimer : private folly::AsyncTimeout,
void scheduleTimeoutImpl(Callback* callback, void scheduleTimeoutImpl(Callback* callback,
std::chrono::milliseconds timeout); std::chrono::milliseconds timeout);
template <class F>
void scheduleTimeoutFn(F fn, std::chrono::milliseconds timeout) {
struct Wrapper : Callback {
Wrapper(F fn) : fn_(std::move(fn)) {}
void timeoutExpired() noexcept override {
try {
fn_();
} catch (std::exception const& e) {
LOG(ERROR) << e.what();
} catch (...) { }
delete this;
}
F fn_;
};
Wrapper* w = new Wrapper(std::move(fn));
scheduleTimeout(w, timeout);
}
/** /**
* Return the number of currently pending timeouts * Return the number of currently pending timeouts
*/ */
......
...@@ -56,11 +56,14 @@ class TestTimeoutDelayed : public TestTimeout { ...@@ -56,11 +56,14 @@ class TestTimeoutDelayed : public TestTimeout {
} }
}; };
struct HHWheelTimerTest : public ::testing::Test {
EventBase eventBase;
};
/* /*
* Test firing some simple timeouts that are fired once and never rescheduled * Test firing some simple timeouts that are fired once and never rescheduled
*/ */
TEST(HHWheelTimerTest, FireOnce) { TEST_F(HHWheelTimerTest, FireOnce) {
EventBase eventBase;
StackWheelTimer t(&eventBase, milliseconds(1)); StackWheelTimer t(&eventBase, milliseconds(1));
const HHWheelTimer::Callback* nullCallback = nullptr; const HHWheelTimer::Callback* nullCallback = nullptr;
...@@ -99,8 +102,7 @@ TEST(HHWheelTimerTest, FireOnce) { ...@@ -99,8 +102,7 @@ TEST(HHWheelTimerTest, FireOnce) {
/* /*
* Test scheduling a timeout from another timeout callback. * Test scheduling a timeout from another timeout callback.
*/ */
TEST(HHWheelTimerTest, TestSchedulingWithinCallback) { TEST_F(HHWheelTimerTest, TestSchedulingWithinCallback) {
EventBase eventBase;
StackWheelTimer t(&eventBase, milliseconds(10)); StackWheelTimer t(&eventBase, milliseconds(10));
const HHWheelTimer::Callback* nullCallback = nullptr; const HHWheelTimer::Callback* nullCallback = nullptr;
...@@ -126,8 +128,7 @@ TEST(HHWheelTimerTest, TestSchedulingWithinCallback) { ...@@ -126,8 +128,7 @@ TEST(HHWheelTimerTest, TestSchedulingWithinCallback) {
* Test cancelling a timeout when it is scheduled to be fired right away. * Test cancelling a timeout when it is scheduled to be fired right away.
*/ */
TEST(HHWheelTimerTest, CancelTimeout) { TEST_F(HHWheelTimerTest, CancelTimeout) {
EventBase eventBase;
StackWheelTimer t(&eventBase, milliseconds(1)); StackWheelTimer t(&eventBase, milliseconds(1));
// Create several timeouts that will all fire in 5ms. // Create several timeouts that will all fire in 5ms.
...@@ -208,8 +209,7 @@ TEST(HHWheelTimerTest, CancelTimeout) { ...@@ -208,8 +209,7 @@ TEST(HHWheelTimerTest, CancelTimeout) {
* Test destroying a HHWheelTimer with timeouts outstanding * Test destroying a HHWheelTimer with timeouts outstanding
*/ */
TEST(HHWheelTimerTest, DestroyTimeoutSet) { TEST_F(HHWheelTimerTest, DestroyTimeoutSet) {
EventBase eventBase;
HHWheelTimer::UniquePtr t( HHWheelTimer::UniquePtr t(
new HHWheelTimer(&eventBase, milliseconds(1))); new HHWheelTimer(&eventBase, milliseconds(1)));
...@@ -250,8 +250,7 @@ TEST(HHWheelTimerTest, DestroyTimeoutSet) { ...@@ -250,8 +250,7 @@ TEST(HHWheelTimerTest, DestroyTimeoutSet) {
/* /*
* Test the tick interval parameter * Test the tick interval parameter
*/ */
TEST(HHWheelTimerTest, AtMostEveryN) { TEST_F(HHWheelTimerTest, AtMostEveryN) {
EventBase eventBase;
// Create a timeout set with a 10ms interval, to fire no more than once // Create a timeout set with a 10ms interval, to fire no more than once
// every 3ms. // every 3ms.
...@@ -337,8 +336,7 @@ TEST(HHWheelTimerTest, AtMostEveryN) { ...@@ -337,8 +336,7 @@ TEST(HHWheelTimerTest, AtMostEveryN) {
* Test an event loop that is blocking * Test an event loop that is blocking
*/ */
TEST(HHWheelTimerTest, SlowLoop) { TEST_F(HHWheelTimerTest, SlowLoop) {
EventBase eventBase;
StackWheelTimer t(&eventBase, milliseconds(1)); StackWheelTimer t(&eventBase, milliseconds(1));
TestTimeout t1; TestTimeout t1;
...@@ -381,3 +379,20 @@ TEST(HHWheelTimerTest, SlowLoop) { ...@@ -381,3 +379,20 @@ TEST(HHWheelTimerTest, SlowLoop) {
T_CHECK_TIMEOUT(start2, t2.timestamps[0], milliseconds(10), milliseconds(1)); T_CHECK_TIMEOUT(start2, t2.timestamps[0], milliseconds(10), milliseconds(1));
T_CHECK_TIMEOUT(start2, end2, milliseconds(10), milliseconds(1)); T_CHECK_TIMEOUT(start2, end2, milliseconds(10), milliseconds(1));
} }
TEST_F(HHWheelTimerTest, lambda) {
StackWheelTimer t(&eventBase, milliseconds(1));
size_t count = 0;
t.scheduleTimeoutFn([&]{ count++; }, milliseconds(1));
eventBase.loop();
EXPECT_EQ(1, count);
}
// shouldn't crash because we swallow and log the error (you'll have to look
// at the console to confirm logging)
TEST_F(HHWheelTimerTest, lambdaThrows) {
StackWheelTimer t(&eventBase, milliseconds(1));
t.scheduleTimeoutFn([&]{ throw std::runtime_error("foo"); },
milliseconds(1));
eventBase.loop();
}
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