Commit ee33c57f authored by Marshall Cline's avatar Marshall Cline Committed by Facebook Github Bot

faster(sometimes) interrupt-handler for Promise/Future

Summary: Avoid overhead of std::function (virtual fn, possible malloc) when the interrupt msg reaches the core before the interrupt handler (the former in future.raise(), the latter in promise.setInterruptHandler()).

Reviewed By: yfeldblum

Differential Revision: D7994756

fbshipit-source-id: 58827e7ac320b6585f1a1c3df08932bbe38f91ee
parent 126f7ac8
......@@ -120,9 +120,9 @@ void Promise<T>::setException(exception_wrapper ew) {
}
template <class T>
void Promise<T>::setInterruptHandler(
std::function<void(exception_wrapper const&)> fn) {
getCore().setInterruptHandler(std::move(fn));
template <typename F>
void Promise<T>::setInterruptHandler(F&& fn) {
getCore().setInterruptHandler(std::forward<F>(fn));
}
template <class T>
......
......@@ -93,7 +93,11 @@ class Promise {
/// bother to set one then you probably will want to fulfill the promise with
/// an exception (or special value) indicating how the interrupt was
/// handled.
void setInterruptHandler(std::function<void(exception_wrapper const&)>);
///
/// `fn` must be copyable and must be invocable with
/// `exception_wrapper const&`
template <typename F>
void setInterruptHandler(F&& fn);
/// Sugar to fulfill this Promise<Unit>
template <class B = T>
......
......@@ -245,13 +245,14 @@ class Core final {
}
/// Call only from Promise thread
void setInterruptHandler(std::function<void(exception_wrapper const&)> fn) {
template <typename F>
void setInterruptHandler(F&& fn) {
std::lock_guard<SpinLock> lock(interruptLock_);
if (!hasResult()) {
if (interrupt_) {
fn(*interrupt_);
fn(as_const(*interrupt_));
} else {
setInterruptHandlerNoLock(std::move(fn));
setInterruptHandlerNoLock(std::forward<F>(fn));
}
}
}
......
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