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