From 5ae4bbcfd58809c7ec56fdc85de35893a0f92d58 Mon Sep 17 00:00:00 2001 From: kfernandez31 Date: Fri, 23 Dec 2022 11:32:14 +0100 Subject: [PATCH 1/5] Added support for seastar (cxx_async_seastar.h), gcc flag -fcoroutines to build.rs and updated README --- README.md | 5 +- cxx-async/build.rs | 2 + cxx-async/include/rust/cxx_async_seastar.h | 134 +++++++++++++++++++++ 3 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 cxx-async/include/rust/cxx_async_seastar.h diff --git a/README.md b/README.md index b3222a6..fc3f756 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,8 @@ be tightly coupled to libraries like `boost::asio`.) If you're writing server co use `cxx-async`, but you will need to ensure that both the Rust and C++ sides run separate I/O executors. -`cxx-async` aims for compatibility with popular C++ coroutine support libraries. Right now, both -the lightweight [`cppcoro`](https://github.com/lewissbaker/cppcoro) and the more comprehensive -[Folly](https://github.com/facebook/folly/) are supported. Pull requests are welcome to support +`cxx-async` aims for compatibility with popular C++ coroutine support libraries. The ones supported right now are the lightweight [`cppcoro`](https://github.com/lewissbaker/cppcoro), the more comprehensive +[Folly](https://github.com/facebook/folly/) and Scylla's [Seastar](https://github.com/scylladb/seastar). Pull requests are welcome to support others. ## Quick tutorial diff --git a/cxx-async/build.rs b/cxx-async/build.rs index d561d9b..d923fca 100644 --- a/cxx-async/build.rs +++ b/cxx-async/build.rs @@ -29,6 +29,7 @@ fn main() { println!("cargo:rerun-if-changed=include/rust/cxx_async.h"); println!("cargo:rerun-if-changed=include/rust/cxx_async_cppcoro.h"); println!("cargo:rerun-if-changed=include/rust/cxx_async_folly.h"); + println!("cargo:rerun-if-changed=include/rust/cxx_async_seastar.h"); println!("cargo:rustc-cfg=built_with_cargo"); @@ -37,6 +38,7 @@ fn main() { .files(&vec!["src/cxx_async.cpp"]) .flag_if_supported("-std=c++20") .flag_if_supported("-fcoroutines-ts") + .flag_if_supported("-fcoroutines") .include("include") .compile("cxx-async"); } diff --git a/cxx-async/include/rust/cxx_async_seastar.h b/cxx-async/include/rust/cxx_async_seastar.h new file mode 100644 index 0000000..16909c2 --- /dev/null +++ b/cxx-async/include/rust/cxx_async_seastar.h @@ -0,0 +1,134 @@ +/* + * This file is open source software, licensed to you under the terms + * of the Apache License, Version 2.0 (the "License"). See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. You may not use this file except in compliance with the License. + * + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +/* + * Copyright (C) 2015 Cloudius Systems, Ltd. + */ + +// cxx-async/include/rust/cxx_async_seastar.h + +#ifndef RUST_CXX_ASYNC_SEASTAR_H +#define RUST_CXX_ASYNC_SEASTAR_H + +#include +#include +#include +#include "rust/cxx_async.h" + +template +struct cxx_awaiter { + seastar::future _future; +public: + explicit cxx_awaiter(seastar::future&& f) noexcept : _future(std::move(f)) { } + + cxx_awaiter(const cxx_awaiter&) = delete; + cxx_awaiter(cxx_awaiter&&) = delete; + + bool await_ready() const noexcept { return _future.available(); } + + template + void await_suspend(SEASTAR_INTERNAL_COROUTINE_NAMESPACE::coroutine_handle hndl) noexcept { + seastar::task* t = seastar::make_task([hndl = std::move(hndl)] { + hndl.resume(); + }); + + if (!_future.available()) { + _future.set_coroutine(*t); + } else { + schedule(t); + } + } + + std::tuple await_resume() { return _future.get(); } +}; + +template +struct cxx_awaiter { + seastar::future _future; +public: + explicit cxx_awaiter(seastar::future&& f) noexcept : _future(std::move(f)) { } + + cxx_awaiter(const cxx_awaiter&) = delete; + cxx_awaiter(cxx_awaiter&&) = delete; + + bool await_ready() const noexcept { return _future.available(); } + + template + void await_suspend(SEASTAR_INTERNAL_COROUTINE_NAMESPACE::coroutine_handle hndl) noexcept { + seastar::task* t = seastar::make_task([hndl = std::move(hndl)] { + hndl.resume(); + }); + + if (!_future.available()) { + _future.set_coroutine(*t); + } else { + schedule(t); + } + } + + T await_resume() { return _future.get0(); } +}; + +template<> +struct cxx_awaiter<> { + seastar::future<> _future; +public: + explicit cxx_awaiter(seastar::future<>&& f) noexcept : _future(std::move(f)) { } + + cxx_awaiter(const cxx_awaiter&) = delete; + cxx_awaiter(cxx_awaiter&&) = delete; + + bool await_ready() const noexcept { return _future.available(); } + + template + void await_suspend(SEASTAR_INTERNAL_COROUTINE_NAMESPACE::coroutine_handle hndl) noexcept { + seastar::task* t = seastar::make_task([hndl = std::move(hndl)] { + hndl.resume(); + }); + + if (!_future.available()) { + _future.set_coroutine(*t); + } else { + schedule(t); + } + } + + void await_resume() { _future.get(); } +}; + +namespace rust { +namespace async { + +template +class AwaitTransformer< + seastar::future, + Future, + void> { + AwaitTransformer() = delete; + + public: + static auto await_transform( + RustPromiseBase& promise, + seastar::future&& future) noexcept { + return cxx_awaiter(std::move(future)); + } +}; + +} // namespace async +} // namespace rust + +#endif // RUST_CXX_ASYNC_SEASTAR_H From 74bc92eb46c07f25ac79277e7bdd6c88ceec2a1c Mon Sep 17 00:00:00 2001 From: kfernandez31 Date: Sun, 25 Dec 2022 14:28:10 +0100 Subject: [PATCH 2/5] Added a missing copy call for cxx_async_seastar.h in build.rs --- cxx-async/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cxx-async/build.rs b/cxx-async/build.rs index d923fca..b960eb7 100644 --- a/cxx-async/build.rs +++ b/cxx-async/build.rs @@ -16,7 +16,7 @@ fn main() { } drop(fs::create_dir_all(&dest_include_path)); - for header in &["cxx_async.h", "cxx_async_cppcoro.h", "cxx_async_folly.h"] { + for header in &["cxx_async.h", "cxx_async_cppcoro.h", "cxx_async_folly.h", "cxx_async_seastar.h"] { drop(fs::copy( Path::join(&src_include_path, header), Path::join(&dest_include_path, header), From 6aed6242d23f44553c732d42b38a04fd9ac02f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20J=C4=99drzejczak?= Date: Mon, 2 Jan 2023 19:02:08 +0100 Subject: [PATCH 3/5] Move cxx_awaiter to namespace async::rust --- cxx-async/include/rust/cxx_async_seastar.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cxx-async/include/rust/cxx_async_seastar.h b/cxx-async/include/rust/cxx_async_seastar.h index 16909c2..2595d6f 100644 --- a/cxx-async/include/rust/cxx_async_seastar.h +++ b/cxx-async/include/rust/cxx_async_seastar.h @@ -29,6 +29,9 @@ #include #include "rust/cxx_async.h" +namespace rust { +namespace async { + template struct cxx_awaiter { seastar::future _future; @@ -110,9 +113,6 @@ struct cxx_awaiter<> { void await_resume() { _future.get(); } }; -namespace rust { -namespace async { - template class AwaitTransformer< seastar::future, From 4d856eb6e8057eb22de22d56678a5e7b4b087adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20J=C4=99drzejczak?= Date: Mon, 2 Jan 2023 19:04:12 +0100 Subject: [PATCH 4/5] Fix unused parameter warning in await_transform --- cxx-async/include/rust/cxx_async_seastar.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cxx-async/include/rust/cxx_async_seastar.h b/cxx-async/include/rust/cxx_async_seastar.h index 2595d6f..8020b48 100644 --- a/cxx-async/include/rust/cxx_async_seastar.h +++ b/cxx-async/include/rust/cxx_async_seastar.h @@ -122,7 +122,7 @@ class AwaitTransformer< public: static auto await_transform( - RustPromiseBase& promise, + [[maybe_unused]] RustPromiseBase& promise, seastar::future&& future) noexcept { return cxx_awaiter(std::move(future)); } From aaa5950d6b71a0c362b83c8a505149c143c766bb Mon Sep 17 00:00:00 2001 From: sylwiaszunejko Date: Sun, 5 Feb 2023 17:03:31 +0100 Subject: [PATCH 5/5] Replace the removed header with the current one and correct license --- cxx-async/include/rust/cxx_async_seastar.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cxx-async/include/rust/cxx_async_seastar.h b/cxx-async/include/rust/cxx_async_seastar.h index 8020b48..cc79d09 100644 --- a/cxx-async/include/rust/cxx_async_seastar.h +++ b/cxx-async/include/rust/cxx_async_seastar.h @@ -16,7 +16,7 @@ * under the License. */ /* - * Copyright (C) 2015 Cloudius Systems, Ltd. + * Copyright (C) 2023 ScyllaDB, Ltd. */ // cxx-async/include/rust/cxx_async_seastar.h @@ -25,9 +25,9 @@ #define RUST_CXX_ASYNC_SEASTAR_H #include -#include +#include #include -#include "rust/cxx_async.h" +#include "cxx_async.h" namespace rust { namespace async { @@ -44,7 +44,7 @@ struct cxx_awaiter { bool await_ready() const noexcept { return _future.available(); } template - void await_suspend(SEASTAR_INTERNAL_COROUTINE_NAMESPACE::coroutine_handle hndl) noexcept { + void await_suspend(std::coroutine_handle hndl) noexcept { seastar::task* t = seastar::make_task([hndl = std::move(hndl)] { hndl.resume(); }); @@ -71,7 +71,7 @@ struct cxx_awaiter { bool await_ready() const noexcept { return _future.available(); } template - void await_suspend(SEASTAR_INTERNAL_COROUTINE_NAMESPACE::coroutine_handle hndl) noexcept { + void await_suspend(std::coroutine_handle hndl) noexcept { seastar::task* t = seastar::make_task([hndl = std::move(hndl)] { hndl.resume(); }); @@ -98,7 +98,7 @@ struct cxx_awaiter<> { bool await_ready() const noexcept { return _future.available(); } template - void await_suspend(SEASTAR_INTERNAL_COROUTINE_NAMESPACE::coroutine_handle hndl) noexcept { + void await_suspend(std::coroutine_handle hndl) noexcept { seastar::task* t = seastar::make_task([hndl = std::move(hndl)] { hndl.resume(); });