Seastar applications obviously cannot use the Posix sleep() function, or
the entire thread will block. This patch implements future<> sleep(duration)
where as expected, the future becomes ready when the given duration passes.
For example, one can do:
sleep(1s).then([] { std::cout << "Done.\n"; });
This can be useful as an example of futures and continuations in the
Seastar tutorial, and people might find other uses for it.
This sleep() is implemented in terms of timer<>. sleep() is easier to use
and more aligned with the rest of Seastar (it uses then() for the
continuation instead of a set_callback() method). The downside of sleep()
compared to a timer is that it cannot be canceled once started.
In this version, sleep() is implemented without shared_ptr, making the
implementation a tiny bit more efficient. There is still a heap allocation
(this is unavoidable because std::function requires a copyable type)
but no reference counting. Unfortunately, this requires us to use bare
"new" and "delete".
Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
engine_exit() without a parameter is meant to do engine().exit(0).
We do this, but forget to return from this function, so after calling
engine().exit(0), it continued on and crashed.
Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
This patch makes compiling a file "hello.cc" using seastar as simple as:
g++ `pkg-config --cflags --libs build/release/seastar.pc` hello.cc
Our current build system makes it very hard for users to build a project
*using* Seastar - basically requiring them to integrate their project into
the Seastar tree and its Makefile into our "ninja" framework.
This patch simplifies things considerably by doing two things:
First it builds an archive of all Seastar objects - build/$mode/libseastar.a.
But this in itself is not enough - the user wouldn't know how to use it
(currently, -Wl,--whole-archive is needed, unfortunately, because of reliance
of C++ static constructors), and will also need a long list of other
libraries, as wall as various definitions and include paths during compilation.
The solution is to use pkg-config, which has become the de-facto standard
method on Linux for makefiles to figure out how to compile with a certain
library. With this patch, someone can do this for example, to compile
tests/fileiotests.cc:
g++ `pkg-config --cflags --libs build/release/seastar.pc` tests/fileiotest.cc
Note how we have a different ".pc" file for each mode, with the appropriate
compile and link flags. A more eleborate example with separate compile and
link stages will use "pkg-config --cflags" on the compilation stage, and
"--libs" on the linking stage.
Eventually, we should have a "ninja install", which will install libseastar.a
and seastar.pc to their system-wide default location, and then the above
command line will become as simple as:
g++ `pkg-config --cflags --libs seastar` tests/fileiotest.cc
Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
The previous patch moved most of the functionality of net::packed<>
into a new template unaligned<> (in core/unaligned.hh). So in this
patch we implement net::packed<> in terms of unaligned<>. The former
is basically the same as the latter, with the addition of the
"adjust_endianness" feature that the networking code expects.
Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
This patch adds a new header file, "core/unaligned.hh", which defines a
new operation, unaligned_cast<T*>(p). This works exctly like
reinterpret_cast<T*>(p) except it is safe to use even when the address
of p is not a multiple of alignof(T).
A long comment in the header file explains why this unaligned_cast<>
is necessary on some esoteric architectures and to quiet gcc's
-fsanitize=alignment.
The header file also defines a new template for holding an unaligned
version of type - unaligned<T>. unaligned<T> is almost identical to our
existing net::packed<>, so the next patch will implement net::packed
in terms of unaligned<>.
The unaligned_cast<> and unaligned<> templates are of course generally
useful outside the network code, which is why I wanted them out of the
networking header files and namespace.
Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
Makes invoking non-copyable lambdas possible:
distributed<T> t;
non_copyable_type x;
t.invoke_on(0, [x = std::move(x)] (auto& t) {});
As a side effect this could save some copyable lambdas from being
needlesly copied.
To register rpc handler func(param1, param2, param3) both server and client
auto remote_func = myrpc.register_handler(id, func);
This call will return another function that client can use to invoke RPC
calls like this:
remote_func(client, param1, param2, param3);
This call will return future<> with func() result.
SEASTAR_TEST_CASE that did not execute a single BOOST_XXX check was
maakred as "[Message] - Test case .... did not check any assertions" and
is placed in /usr/include/boost/test/impl/results_collector instead of
the correct test file.
Signed-off-by: Shlomi Livne <shlomi@cloudius-systems.com>
when_all() tests generate two million calls to BOOST_REQUIRE(), which
overwhelms the test result parser. Replace with two calls and use all_of()
to process the result array.
One file, seastar.hh, containing all the main entry points as free functions.
Most classes are forward-declared to avoid the need to #include the entire
world.
Boost XML report files can be parsed by Jenkins and provide a mean for
jenkins to track specific test cases status.
Signed-off-by: Shlomi Livne <shlomi@cloudius-systems.com>
Add a when_all() variant that waits for a runtime variable number of
futures, all of the same type. The function returns a future containing
a vector of all input futures, each in ready state, containing either
a result or an exception.
Currently we have one version of when_all(), that accepts a compile
type variable number of independently typed futures. We wish to add more
overloads, but for that, we must ensure that this variant doesn't match them.
Accomplish this by requiring that the first argument be a future, and don't
accept any other type.
allocate_buffer was added to data_sink as a virtual method, so that
a class extending it can override its implementation.
output_stream will also start using allocate_buffer whenever it
needs a temporary buffer.
In fstream.cc, use the convenient new temporary_buffer<char>::aligned()
function for creating an aligned temporary buffer - instead of repeating
its implementation.
Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
The file_input_stream interface was messy: it was not fiber safe (e.g., code
doing seek() in the middle of an ongoing read_exactly()), and went against
the PIMPL philosophy.
So this patch removes the file_input_stream class, and replaces it with a
completely different design:
We now have in fstream.hh a global function:
input_stream<char>
make_file_input_stream(
lw_shared_ptr<file> file, uint64_t offset = 0,
uint64_t buffer_size = 8192);
In other words, instead of "seeking" in an input stream, we just open a new
input stream object at a particular offset of the given file. Multiple input
streams might be concurrently active on the same file.
Note how make_file_input_stream now returns a regular "input_stream", not a
subtype, and it can be used just like any normal input_stream to read the stream
starting at the given position.
This patch makes "input_stream" a "final" type: we no longer subclass it in our
code, and we shouldn't in the future because it goes against the PIMPL design
(the subclass should be of the inner workings, like the data_source_impl, not
of input_stream).
Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>