.then()'s return type is a complex template, which needs to be mangled into
the function's name. Move the return type into a defaulted template type
parameter, so that the entire type expression is eliminated, being replaced
by the result type.
Saves about 1% compile time and 3% object size on futures_test.o.
This patch adds a "class future" method for handling an exception result
of the future. It is impossible to discard a future's exception while passing
through the value of the result (what will we pass in the case of
exception?), so we discard the result as well.
An example of how this can be used, to log an error (but otherwise do
nothing) if removing a file fails:
remove_file(filename).handle_exception(
[] (std::exception_ptr eptr) {
print("Exception when deleting file: %s", eptr);
});
Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
When a promise that still tracks its future is destroyed, but after
future::get() or future::then() was called, the promise thinks it was
destroyed before generating a value, and fails an assertion.
Fix be detaching the promise from the future as soon as get() or then()
remove the value.
gcc makes poor inlining decisions sometimes, which cause all the value-
tracking optimizations to be lost. Forcing it to inline (particularly
around destructors) allows ready futures to be inlined with fewer always-
true tests and data movements.
From http://en.cppreference.com/w/cpp/language/constexpr:
A constexpr specifier used in an object declaration implies const.
However, We can not change from
static constexpr const char* TIME_FORMAT = "%a %b %d %I:%M:%S %Z %Y";
to
static constexpr char* TIME_FORMAT = "%a %b %d %I:%M:%S %Z %Y";
The compiler complains:
In file included from json/formatter.cc:22:0:
json/formatter.hh:132:42: error: deprecated conversion from string
constant to ‘char*’ [-Werror=write-strings]
static constexpr char* TIME_FORMAT = "%a %b %d %I:%M:%S %Z %Y";
Since, unlike const, constexpr does not modify a type. It just applies
to an object (or function), and incidentally implies const to the
top-level type.
Add a thread class that can be used to launch a blockable thread of
execution. Within a thread, future<>::get() can be called on an
unavailable future, in which case it blocks until the future is made ready.
Add "finally" continuation overload for functions returning future type that
awaits finishing the continuation in question before continuing the "present"
one. I.e. a wrapper around "then_wrapped" to remove the need to deal with the
original return value.
Signed-off-by: Calle Wilund <calle@cloudius-systems.com>
The ".or_terminate()" continuation is needed when one needs to exit the
application on an unhandled exception, instead of just letting the event
loop continue to spin forever.
or_terminate() currently calls std::terminate() which only incidentally
(as a gcc-specific implementation) prints out the exception's type; It
then calls abort(), which results in a painfully slow core dump. This
abort() is NOT helpful, because at that point the debugger can only find
where abort() was called, not where the original exception was thrown (see
issue #32).
So instead of calling std::terminate(), this patch switches to calling
engine().exit(), to cleanly shut down the application, without dumping
core. It also prints, like gcc's std::terminate(), the exception's type.
This printing requires non-standard gcc extensions.
Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
Calling state.get() will throw the exception instead of calling the function,
thus denying the called function the chance to deal with the exception.
Fix by constructing the future directly from state.
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.
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.
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().
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.
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.