2 * Copyright 2015 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #include "ThreadWheelTimekeeper.h"
18 #include <folly/Singleton.h>
19 #include <folly/futures/Future.h>
25 Singleton<ThreadWheelTimekeeper> timekeeperSingleton_;
27 // Our Callback object for HHWheelTimer
28 struct WTCallback : public folly::HHWheelTimer::Callback {
29 // Only allow creation by this factory, to ensure heap allocation.
30 static WTCallback* create(EventBase* base) {
31 // optimization opportunity: memory pool
32 return new WTCallback(base);
35 Future<Unit> getFuture() {
36 return promise_.getFuture();
41 Promise<Unit> promise_;
43 explicit WTCallback(EventBase* base)
45 promise_.setInterruptHandler(
46 std::bind(&WTCallback::interruptHandler, this));
49 void timeoutExpired() noexcept override {
54 void interruptHandler() {
55 base_->runInEventBaseThread([=] {
65 ThreadWheelTimekeeper::ThreadWheelTimekeeper() :
66 thread_([this]{ eventBase_.loopForever(); }),
67 wheelTimer_(new HHWheelTimer(&eventBase_, std::chrono::milliseconds(1)))
69 eventBase_.waitUntilRunning();
70 eventBase_.runInEventBaseThread([this]{
72 eventBase_.setName("FutureTimekeepr");
76 ThreadWheelTimekeeper::~ThreadWheelTimekeeper() {
77 eventBase_.runInEventBaseThreadAndWait([this]{
78 wheelTimer_->cancelAll();
79 eventBase_.terminateLoopSoon();
84 Future<Unit> ThreadWheelTimekeeper::after(Duration dur) {
85 auto cob = WTCallback::create(&eventBase_);
86 auto f = cob->getFuture();
87 eventBase_.runInEventBaseThread([=]{
88 wheelTimer_->scheduleTimeout(cob, dur);
95 Timekeeper* getTimekeeperSingleton() {
96 return timekeeperSingleton_.get();