Commit Graph

27 Commits

Author SHA1 Message Date
Avi Kivity
7dfd7de8cd future: optimize data-less future<>
A future that does not carry any data (future<>) and its sibling (promise<>)
are heavily used in the code.  We can optimize them by overlaying the
future's payload, which in this case can only be an std::exception_ptr,
with the future state, as a pointer and an enum have disjoint values.

This of course depends on std::exception_ptr being implemented as a pointer,
but as it happens, it is.

With this, sizeof(future<>) is reduced from 24 bytes to 16 bytes.
2014-12-09 10:08:48 +02:00
Tomasz Grabiec
b6511ce3f4 core: add future::discard_result()
Use when you don't want to care about the result and just want to
return a future<>.

The current implementation may not be the most optimal way to do it
but it can be improved later if there's need.
2014-11-09 16:33:34 +02:00
Gleb Natapov
e5dfd8e863 future: limit number of ready futures that are executed without scheduling a task
Otherwise stack may overflow if a very long chain of ready futures is
executed.
2014-11-04 15:18:32 +02:00
Avi Kivity
3d414111eb future: make .rescue() require an rvalue reference for its future
This makes it harder to misuse.
2014-10-30 14:07:42 +02:00
Avi Kivity
c4bc67414e future: add then_wrapped()
Unlike future::then(), which unwraps the value, then_wrapped() keeps it
wrapped in a future<>, so if it is exceptional, it can still be accessed.

This is similar to the proposed std::future::then(), so we should later
rename it to match (and rename the existing future::then() to future::next().
2014-10-30 13:55:31 +02:00
Tomasz Grabiec
eb84a3b78b core: fix future::forward_to()
It did not handle properly the case when the target promise's future gets dead
without installing a callback or the future was never installed. The
mishanlding of the former case was causing httpd to abort on SMP.
2014-10-27 15:58:57 +02:00
Avi Kivity
0d745abf69 future: sprinke noexcept everywhere
When used correctly, noexcept allows containers to optimize their reallocation
code.
2014-10-26 14:34:56 +02:00
Tomasz Grabiec
74ac65a491 core: optimize future::forward_to()
We can avoid extra allocation and chaining by linking the current
future's promise with the target promise's future, as if the target
promise was moved into the current future's promise.
2014-10-24 19:40:48 +03:00
Tomasz Grabiec
ca077f33ef core: introduce or_terminate()
Calls std::terminate() when future fails. It can be used like this:

  do_something([] {}).or_terminate();
2014-10-15 15:59:41 +02:00
Tomasz Grabiec
cf7a084457 core: move some of the networking abstractions to net/api.hh 2014-10-06 18:34:28 +02:00
Avi Kivity
ef96af29f2 future: avoid generalized lambda in forward_to()
Crashes gdb with -O0.
2014-10-05 15:44:49 +03:00
Tomasz Grabiec
6fa9cd7ac9 core: introduce do_until() and keep_doing() 2014-10-04 11:27:23 +02:00
Tomasz Grabiec
6fa3212888 core: fix missing error propagation when intermediate future is involved
Test case (added in the next patch):

    promise<> p1;
    promise<> p2;

    auto f = p1.get_future().then([f = std::move(p2.get_future())] () mutable {
        return std::move(f); // this future will fail
    }).then([] {
        // never reached, that's ok
    });

    p1.set_value();
    p2.set_exception(std::runtime_error("boom"));

    // f should get resolved eventually with error, but was not
2014-10-01 13:45:28 +02:00
Tomasz Grabiec
d9bf08c1b3 core: introduce future::finally()
The callback passed to it will be executed when future gets resolved,
successfully or not. The returned future will mimic the state of the
target future.
2014-10-01 13:45:28 +02:00
Tomasz Grabiec
fcb55c1f04 core: introduce future::forward_to()
It causes that when future is resolved, the target promise will be
resolved too with the same state.
2014-10-01 13:45:28 +02:00
Tomasz Grabiec
07d6df11a8 core: introduce make_exception_future() which works with exception objects 2014-10-01 13:45:25 +02:00
Tomasz Grabiec
125a696d6c core: introduce promise::set_exception() which works with exception objects 2014-10-01 13:45:22 +02:00
Tomasz Grabiec
eeea3640f2 core: make future::rescue() return a future<>
This will allow to compose rescue() just like then().
2014-10-01 13:21:09 +02:00
Tomasz Grabiec
5f2e06beda core: make future's result obtainable via future::rescue()
This will allow the user to have one handler for both success and
failure. This simplifies client code a bit when both paths need to
work on the same object. Having to split the function into two
callbacks, one of which is passed to then() and the other to rescue()
on a resulting promise, would make it necessary to wrap the object in
a shared_ptr, which is suboptimal.
2014-10-01 13:21:02 +02:00
Tomasz Grabiec
9816422a67 core: fix SIGSEGV in future::then()
This fixes SIGSEGV which happens when a promise gets resolved and
dies before the callback is registerred via then(). The latter assumes
that _promise must not be nullptr if the state is not resolved
yet. The dying promise should move the resolved state into the
future's local state.
2014-09-22 23:11:13 +03:00
Avi Kivity
3b1d37ff2f future: implement available()
As the whole point of future/promise is to decouple the producer from the
consumer, available() is not generally useful.  However it can still be
useful in special cases when we want to know who got there first.

One of them is deciding when to drop packets -- if the consumer is not
ready, and no queue space is available, we should just drop the packet
instead of waiting for the consumer.
2014-09-22 11:25:54 +03:00
Avi Kivity
1d11ecfbcd future: implement move assignment 2014-09-22 11:25:54 +03:00
Avi Kivity
64ce457053 future: fix move constructor
If we're no longer tracking the promise (either gone, or never existed),
we shouldn't update it.
2014-09-22 11:25:54 +03:00
Avi Kivity
f7a0a3cdc6 future: reduce allocations
Instead of keeping the future state in heap storage, referenced from
the promise/future/task, keep the state in the promise or future and only
allocate it on the heap as a last resort (for a stack).

Improves httpd throughtput by ~20%.
2014-09-15 14:31:58 +03:00
Avi Kivity
1385a5278e core: get rid of embarassing while () loop in future_state::get() 2014-09-09 12:37:13 +03:00
Avi Kivity
12aba7e9cb core: fix promise move assignment
Leaked if an object was assigned to itself.
2014-09-08 21:00:09 +03:00
Avi Kivity
300abc77d8 core: split future/promise into a new header file 2014-09-04 10:37:59 +03:00