Summary: I think this makes sense, especially if `interrupt_` is really rare.
Test Plan:
============================================================================
folly/futures/test/Benchmark.cpp relative time/iter iters/s
============================================================================
constantFuture 101.25ns 9.88M
promiseAndFuture 92.86% 109.03ns 9.17M
withThen 28.96% 349.65ns 2.86M
----------------------------------------------------------------------------
oneThen 337.33ns 2.96M
twoThens 58.46% 577.06ns 1.73M
fourThens 32.42% 1.04us 961.23K
hundredThens 1.45% 23.24us 43.04K
----------------------------------------------------------------------------
no_contention 4.45ms 224.48
contention 72.89% 6.11ms 163.61
----------------------------------------------------------------------------
throwAndCatch 6.34us 157.77K
throwAndCatchWrapped 95.65% 6.63us 150.91K
throwWrappedAndCatch 142.58% 4.45us 224.95K
throwWrappedAndCatchWrapped 488.86% 1.30us 771.27K
----------------------------------------------------------------------------
throwAndCatchContended 1.01s 987.01m
throwAndCatchWrappedContended 100.03% 1.01s 987.27m
throwWrappedAndCatchContended 148.37% 682.86ms 1.46
throwWrappedAndCatchWrappedContended 18765.19% 5.40ms 185.21
============================================================================
Compare to
D1843129#31 (seems to be an improvement?)
Reviewed By: hans@fb.com
Subscribers: trunkagent, folly-diffs@, jsedgwick, yfeldblum
FB internal diff:
D1847843
Signature: t1:
1847843:
1423855151:
3602d49df245eda3f85325ab5efd63514213ca44
void raise(exception_wrapper e) {
std::lock_guard<decltype(interruptLock_)> guard(interruptLock_);
if (!interrupt_ && !hasResult()) {
- interrupt_ = std::move(e);
+ interrupt_ = folly::make_unique<exception_wrapper>(std::move(e));
if (interruptHandler_) {
- interruptHandler_(interrupt_);
+ interruptHandler_(*interrupt_);
}
}
}
void setInterruptHandler(std::function<void(exception_wrapper const&)> fn) {
std::lock_guard<decltype(interruptLock_)> guard(interruptLock_);
if (!hasResult()) {
- if (!!interrupt_) {
- fn(interrupt_);
+ if (interrupt_) {
+ fn(*interrupt_);
} else {
interruptHandler_ = std::move(fn);
}
std::function<void(Try<T>&&)> callback_ {nullptr};
std::shared_ptr<RequestContext> context_ {nullptr};
std::atomic<Executor*> executor_ {nullptr};
- exception_wrapper interrupt_ {};
+ std::unique_ptr<exception_wrapper> interrupt_ {};
std::function<void(exception_wrapper const&)> interruptHandler_ {nullptr};
};
TEST(Future, coreSize) {
// If this number goes down, it's fine!
// If it goes up, please seek professional advice ;-)
- size_t size = 168;
- if (sizeof(folly::exception_wrapper) == 80) {
- // it contains strings, which can be bigger for -fb builds (e.g. fbstring)
- size = 200;
- }
- EXPECT_EQ(size, sizeof(detail::Core<void>));
+ EXPECT_EQ(128, sizeof(detail::Core<void>));
}
// Future