in dispenso/detail/future_impl.h [266:298]
void addToThenChainOrExecute(SomeFutureImpl* impl, Schedulable& sched, std::launch asyncPolicy) {
if (status_.intrusiveStatus().load(std::memory_order_acquire) == kReady) {
if ((asyncPolicy & std::launch::async) == std::launch::async) {
sched.schedule(OnceFunction(impl, true), ForceQueuingTag());
} else {
sched.schedule(OnceFunction(impl, true));
}
return;
}
constexpr size_t kImplSize = nextPow2(sizeof(ThenChain));
auto* buffer = allocSmallBuffer<kImplSize>();
ThenChain* link = reinterpret_cast<ThenChain*>(buffer);
link->impl = impl;
using NonConstSchedulable = std::remove_const_t<Schedulable>;
NonConstSchedulable* nonConstSched = const_cast<NonConstSchedulable*>(&sched);
link->schedulable = nonConstSched;
if ((asyncPolicy & std::launch::async) == std::launch::async) {
link->invoke = thenChainInvokeAsync<SomeFutureImpl, Schedulable>;
} else {
link->invoke = thenChainInvoke<SomeFutureImpl, Schedulable>;
}
link->next = thenChain_.load(std::memory_order_acquire);
while (!thenChain_.compare_exchange_weak(link->next, link, std::memory_order_acq_rel)) {
}
// Okay, one last thing. It is possible that we added to the thenChain just after
// tryExecuteThenChain was called from run(). We still need to ensure that this work is kicked
// off, so just double check here, and execute if that may have happened.
if (status_.intrusiveStatus().load(std::memory_order_acquire) == kReady) {
tryExecuteThenChain();
}
}