MCPcopy Create free account
hub / github.com/3rdparty/libprocess / after

Method after

include/process/future.hpp:1692–1747  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1690
1691template <typename T>
1692Future<T> Future<T>::after(
1693 const Duration& duration,
1694 lambda::CallableOnce<Future<T>(const Future<T>&)> f) const
1695{
1696 // TODO(benh): Using a Latch here but Once might be cleaner.
1697 // Unfortunately, Once depends on Future so we can't easily use it
1698 // from here.
1699 std::shared_ptr<Latch> latch(new Latch());
1700 std::shared_ptr<Promise<T>> promise(new Promise<T>());
1701
1702 // We need to control the lifetime of the timer we create below so
1703 // that we can force the timer to get deallocated after it
1704 // expires. The reason we want to force the timer to get deallocated
1705 // after it expires is because the timer's lambda has a copy of
1706 // `this` (i.e., a Future) and it's stored in the `onAny` callbacks
1707 // of `this` thus creating a circular reference. By storing a
1708 // `shared_ptr<Option<Timer>>` we're able to set the option to none
1709 // after the timer expires which will deallocate our copy of the
1710 // timer and leave the `Option<Timer>` stored in the lambda of the
1711 // `onAny` callback as none. Note that this is safe because the
1712 // `Latch` makes sure that only one of the callbacks will manipulate
1713 // the `shared_ptr<Option<Timer>>` so there isn't any concurrency
1714 // issues we have to worry about.
1715 std::shared_ptr<Option<Timer>> timer(new Option<Timer>());
1716
1717 typedef lambda::CallableOnce<Future<T>(const Future<T>&)> F;
1718 std::shared_ptr<F> callable(new F(std::move(f)));
1719
1720 // Set up a timer to invoke the callback if this future has not
1721 // completed. Note that we do not pass a weak reference for this
1722 // future as we don't want the future to get cleaned up and then
1723 // have the timer expire because then we wouldn't have a valid
1724 // future that we could pass to `f`! The reference to `this` that is
1725 // captured in the timer will get removed by setting the
1726 // `Option<Timer>` to none (see comment above) either if the timer
1727 // expires or if `this` completes and we cancel the timer (see
1728 // `internal::expired` and `internal::after` callbacks for where we
1729 // force the deallocation of our copy of the timer).
1730 *timer = Clock::timer(
1731 duration,
1732 lambda::bind(&internal::expired<T>, callable, latch, promise, timer,
1733 *this));
1734
1735 onAny(lambda::bind(&internal::after<T>, latch, promise, timer, lambda::_1));
1736
1737 onAbandoned([=]() {
1738 promise->future().abandon();
1739 });
1740
1741 // Propagate discarding up the chain. To avoid cyclic dependencies,
1742 // we keep a weak future in the callback.
1743 promise->future().onDiscard(
1744 lambda::bind(&internal::discard<T>, WeakFuture<T>(*this)));
1745
1746 return promise->future();
1747}
1748
1749

Callers 2

stopMethod · 0.80
TESTFunction · 0.80

Calls 4

bindFunction · 0.85
onAnyFunction · 0.85
abandonMethod · 0.80
futureMethod · 0.80

Tested by 1

TESTFunction · 0.64