summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
fbc4c23)
Summary:
According to folly::Singleton::try_get(), https://fburl.com/23wqby9i, the caller is responsible for handling a nullptr return. In this case, we handle it poorly, via a crash both in production and debug code.
This diff opts for handling the nullptr more gracefully, via a future loaded with an exception.
Reviewed By: yfeldblum
Differential Revision:
D6006864
fbshipit-source-id:
e8fde57ed161b33fa1f157ce663ed85e69640c25
std::shared_ptr<Timekeeper> tks;
if (LIKELY(!tk)) {
tks = folly::detail::getTimekeeperSingleton();
std::shared_ptr<Timekeeper> tks;
if (LIKELY(!tk)) {
tks = folly::detail::getTimekeeperSingleton();
- tk = DCHECK_NOTNULL(tks.get());
+
+ if (UNLIKELY(!tk)) {
+ return makeFuture<Unit>(NoTimekeeper());
+ }
+
[[noreturn]] void throwPredicateDoesNotObtain();
[[noreturn]] void throwPredicateDoesNotObtain();
-struct FOLLY_EXPORT NoFutureInSplitter : FutureException {
+class FOLLY_EXPORT NoFutureInSplitter : FutureException {
+ public:
NoFutureInSplitter() : FutureException("No Future in this FutureSplitter") {}
};
[[noreturn]] void throwNoFutureInSplitter();
NoFutureInSplitter() : FutureException("No Future in this FutureSplitter") {}
};
[[noreturn]] void throwNoFutureInSplitter();
+
+class FOLLY_EXPORT NoTimekeeper : public FutureException {
+ public:
+ NoTimekeeper() : FutureException("No timekeeper available") {}
+};
*/
#include <folly/futures/Timekeeper.h>
*/
#include <folly/futures/Timekeeper.h>
+#include <folly/Singleton.h>
+#include <folly/futures/ThreadWheelTimekeeper.h>
#include <folly/portability/GTest.h>
using namespace folly;
#include <folly/portability/GTest.h>
using namespace folly;
EXPECT_GE(now() - t1, one_ms);
}
EXPECT_GE(now() - t1, one_ms);
}
+TEST(Timekeeper, futureSleepHandlesNullTimekeeperSingleton) {
+ Singleton<ThreadWheelTimekeeper>::make_mock([] { return nullptr; });
+ SCOPE_EXIT {
+ Singleton<ThreadWheelTimekeeper>::make_mock();
+ };
+ EXPECT_THROW(futures::sleep(one_ms).get(), NoTimekeeper);
+}
+
TEST(Timekeeper, futureDelayed) {
auto t1 = now();
auto dur = makeFuture()
TEST(Timekeeper, futureDelayed) {
auto t1 = now();
auto dur = makeFuture()