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
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.
It allows for simpler client code because the client can assume that
when cancel() returns the callback will not run and thus there's no
need to handle the race between timer teardown and execution of the
callback.
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.
Fix error with tcp_test:
terminate called after throwing an instance of
'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_any_cast> >'
what(): boost::bad_any_cast: failed conversion using boost::any_cast
This method, intended for request parsers, receives a stream of temporary
buffers until it determines that parsing is done, at which point it can
return any unconsumed partial buffer back to the input stream.
It is intended as a replacement for read_until(), since it can parse in a
single pass.
Runing on pre-glibc2.18 hosts (like C7) is impossible without this. The
downside is that the developer has to download, build, and install static
versions of libtcmalloc and libaio.
timer_set maintains next timeout so no need to duplicate it.
This also fixes a potential issue, if upon timer expiry no timer is
pending we did not update _next_timeout which will result in timer fd
not being updated upon next arm().
If you don't want to build eveything, you can narrow down the list of
artifacts liek this:
$ ./configure --with tests/test-reactor --with apps/httpd/httpd
It's less awkward to concatenate lists than strings. Having files in a
list is less prone to merge conflicts. It also makes the split() call
unnecessary.
By default both debug and release binaries are built. It makes the
build take longer than necessary, it's rarely needed to have both
versions during development. To build only one of them, do:
$ ./configure --mode debug
$ ninja