Commit 5db8c175 authored by Lewis Baker's avatar Lewis Baker Committed by Facebook GitHub Bot

Change Task::semi() to capture callsite of semi() in detached_task stack-trace

Summary:
The async stack-trace for a coroutine call-stack that was launched
by calling Task<T>::semi() to create a SemiFuture would have as its
first few frames:
- detached_task
- folly::coro::Task::semi::{lambda#1}::operator()
- <the coroutine being launched>

This isn't particularly useful as it doesn't tell you where the coroutine was launched from. The more interesting information here
is the callsite of .semi() rather than the internals of .semi().

This reworks the implementation of .semi() to capture the return-address
of the call to .semi() and then later inject this as the return-address
of the async-frame when the coroutine is eventually launched.

Note: This also now launches the coroutine inline inside the SemiFuture by calling .startInlineImpl(). This should avoid an
extra executor reschedule.

Reviewed By: yfeldblum

Differential Revision: D25415029

fbshipit-source-id: ab24e86b871c78e2c3a9af843e24e2dab3254273
parent cd39f451
......@@ -592,11 +592,24 @@ class FOLLY_NODISCARD Task {
return TaskWithExecutor<T>{std::exchange(coro_, {})};
}
FOLLY_NOINLINE
SemiFuture<folly::lift_unit_t<StorageType>> semi() && {
return makeSemiFuture().deferExTry(
[task = std::move(*this)](
[task = std::move(*this),
returnAddress = FOLLY_ASYNC_STACK_RETURN_ADDRESS()](
const Executor::KeepAlive<>& executor, Try<Unit>&&) mutable {
return std::move(task).scheduleOn(executor.get()).start();
Promise<lift_unit_t<StorageType>> p;
auto sf = p.getSemiFuture();
std::move(task).scheduleOn(executor).startInlineImpl(
[promise = std::move(p)](Try<StorageType>&& result) mutable {
promise.setTry(std::move(result));
},
folly::CancellationToken{},
returnAddress);
return sf;
});
}
......
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