Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci-latest-kernel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ jobs:
-DCONDY_BUILD_EXAMPLES=ON \
-DCONDY_BUILD_BENCHMARKS=ON \
-DCONDY_BUILD_TESTS=ON \
-DCONDY_ENABLE_STDEXEC=ON \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_BUILD_TYPE=Release \
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ jobs:
-DCONDY_BUILD_BENCHMARKS=ON \
-DCONDY_BUILD_TESTS=ON \
-DCONDY_LINK_LIBURING_VERSION=${{ env.LIBURING_VERSION }} \
-DCONDY_ENABLE_STDEXEC=ON \
$SANITIZER_FLAG \
-DCMAKE_C_COMPILER=${{matrix.compiler.cc}} \
-DCMAKE_CXX_COMPILER=${{matrix.compiler.cxx}} \
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci-static-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ jobs:
-DCONDY_BUILD_EXAMPLES=ON \
-DCONDY_BUILD_BENCHMARKS=ON \
-DCONDY_BUILD_TESTS=ON \
-DCONDY_ENABLE_STDEXEC=ON \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_BUILD_TYPE=Debug \
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/ci-toolchain.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ jobs:
-DCONDY_BUILD_BENCHMARKS=ON \
-DCONDY_BUILD_TESTS=ON \
-DCONDY_LINK_LIBURING_VERSION=${{ matrix.liburing-version }} \
-DCONDY_ENABLE_STDEXEC=ON \
-DCMAKE_C_COMPILER=${{ matrix.compiler.cc }} \
-DCMAKE_CXX_COMPILER=${{ matrix.compiler.cxx }} \
-DCMAKE_BUILD_TYPE=Debug
Expand All @@ -53,8 +54,10 @@ jobs:
- name: Build module-hello
# liburing < 2.13 exposes TU-local entities that break GCC modules
# https://github.com/axboe/liburing/issues/1457
# stdexec uses TU-local entities incompatible with GCC C++20 modules
if: >
matrix.generator == 'Ninja'
&& matrix.compiler.cc != 'gcc'
&& !(matrix.compiler.cc == 'gcc' && matrix.liburing-version == '2.3')
run: |
cmake -B ${{github.workspace}}/build_module -G Ninja \
Expand All @@ -68,5 +71,6 @@ jobs:
- name: Run module-hello
if: >
matrix.generator == 'Ninja'
&& matrix.compiler.cc != 'gcc'
&& !(matrix.compiler.cc == 'gcc' && matrix.liburing-version == '2.3')
run: ${{github.workspace}}/build_module/examples/module-hello
20 changes: 20 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ option(CONDY_TESTS_TSAN "Enable thread sanitizer for tests" OFF)
option(CONDY_TESTS_ASAN "Enable address and undefined behavior sanitizers for tests" OFF)
option(CONDY_LINK_LIBURING "Use liburing and link it to condy" ON)
set(CONDY_LINK_LIBURING_VERSION "2.15" CACHE STRING "liburing version to fetch and link")
option(CONDY_ENABLE_STDEXEC "Enable stdexec execution integration" OFF)

# Backward compatibility for the unprefixed option names.
macro(condy_legacy_option legacy new)
Expand All @@ -48,6 +49,7 @@ include(FetchContent)
set(DOXYGEN_AWESOME_CSS_VERSION v2.4.1)
set(DOCTEST_VERSION v2.5.0)
set(LIBURING_VERSION liburing-${CONDY_LINK_LIBURING_VERSION})
set(STDEXEC_VERSION 0a6c3fc4324aed2ce291d49dd228cc3619b24dad)

FetchContent_Declare(
doxygen-awesome-css
Expand All @@ -64,6 +66,11 @@ FetchContent_Declare(
URL https://github.com/axboe/liburing/archive/refs/tags/${LIBURING_VERSION}.tar.gz
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
FetchContent_Declare(
stdexec
URL https://github.com/NVIDIA/stdexec/archive/${STDEXEC_VERSION}.tar.gz
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)

add_library(condy INTERFACE)
target_include_directories(condy INTERFACE include)
Expand Down Expand Up @@ -104,6 +111,19 @@ if(CONDY_LINK_LIBURING)
target_link_libraries(condy INTERFACE uring)
endif()

if(CONDY_ENABLE_STDEXEC)
# stdexec
message(STATUS "Fetching stdexec")
FetchContent_GetProperties(stdexec)
if(NOT stdexec_POPULATED)
FetchContent_Populate(stdexec)
endif()
add_library(stdexec INTERFACE)
target_include_directories(stdexec SYSTEM INTERFACE ${stdexec_SOURCE_DIR}/include)
target_link_libraries(condy INTERFACE stdexec)
target_compile_definitions(condy INTERFACE CONDY_HAS_STDEXEC)
endif()

if(CONDY_BUILD_MODULE)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)
message(STATUS "Configuring C++ module interface in ${CMAKE_CURRENT_SOURCE_DIR}/module")
Expand Down
1 change: 1 addition & 0 deletions include/condy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "condy/channel.hpp" // IWYU pragma: export
#include "condy/coro.hpp" // IWYU pragma: export
#include "condy/cqe_handler.hpp" // IWYU pragma: export
#include "condy/execution.hpp" // IWYU pragma: export
#include "condy/futex.hpp" // IWYU pragma: export
#include "condy/helpers.hpp" // IWYU pragma: export
#include "condy/pmr.hpp" // IWYU pragma: export
Expand Down
26 changes: 17 additions & 9 deletions include/condy/async_operations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -839,10 +839,12 @@ inline auto async_socket_direct(int domain, int type, int protocol,
* @tparam CQEHandler Custom CQE handler for specific result processing.
* @param cmd_func Function to configure sqe for specific command. Signature:
* void(io_uring_sqe *sqe).
* @param handler_args Arguments forwarded to CQEHandler constructor.
*/
template <CQEHandlerLike CQEHandler = SimpleCQEHandler, FdLike Fd,
typename CmdFunc>
inline auto async_uring_cmd(int cmd_op, Fd fd, CmdFunc &&cmd_func) {
typename CmdFunc, typename... Args>
inline auto async_uring_cmd(int cmd_op, Fd fd, CmdFunc &&cmd_func,
Args &&...handler_args) {
auto prep_func = [cmd_op, fd = detail::unwrap_fixed(fd),
cmd_func =
std::forward<CmdFunc>(cmd_func)](detail::Ring *ring) {
Expand All @@ -851,17 +853,19 @@ inline auto async_uring_cmd(int cmd_op, Fd fd, CmdFunc &&cmd_func) {
cmd_func(sqe);
return sqe;
};
auto op = build_op_awaiter<CQEHandler>(std::move(prep_func));
auto op = build_op_awaiter<CQEHandler>(std::move(prep_func),
std::forward<Args>(handler_args)...);
return detail::maybe_flag_fixed_fd(std::move(op), fd);
}

/**
* @copydoc async_uring_cmd
*/
template <CQEHandlerLike CQEHandler = SimpleCQEHandler, FdLike Fd,
typename CmdFunc, typename MultiShotFunc>
typename CmdFunc, typename MultiShotFunc, typename... Args>
inline auto async_uring_cmd_multishot(int cmd_op, Fd fd, CmdFunc &&cmd_func,
MultiShotFunc &&func) {
MultiShotFunc &&func,
Args &&...handler_args) {
auto prep_func = [cmd_op, fd = detail::unwrap_fixed(fd),
cmd_func =
std::forward<CmdFunc>(cmd_func)](detail::Ring *ring) {
Expand All @@ -871,7 +875,8 @@ inline auto async_uring_cmd_multishot(int cmd_op, Fd fd, CmdFunc &&cmd_func,
return sqe;
};
auto op = build_multishot_op_awaiter<CQEHandler>(
std::move(prep_func), std::forward<MultiShotFunc>(func));
std::move(prep_func), std::forward<MultiShotFunc>(func),
std::forward<Args>(handler_args)...);
return detail::maybe_flag_fixed_fd(std::move(op), fd);
}

Expand All @@ -881,10 +886,12 @@ inline auto async_uring_cmd_multishot(int cmd_op, Fd fd, CmdFunc &&cmd_func,
* @tparam CQEHandler Custom CQE handler for specific result processing.
* @param cmd_func Function to configure sqe for specific command. Signature:
* void(io_uring_sqe *sqe).
* @param handler_args Arguments forwarded to CQEHandler constructor.
*/
template <CQEHandlerLike CQEHandler = SimpleCQEHandler, FdLike Fd,
typename CmdFunc>
inline auto async_uring_cmd128(int cmd_op, Fd fd, CmdFunc &&cmd_func) {
typename CmdFunc, typename... Args>
inline auto async_uring_cmd128(int cmd_op, Fd fd, CmdFunc &&cmd_func,
Args &&...handler_args) {
auto prep_func = [cmd_op, fd = detail::unwrap_fixed(fd),
cmd_func =
std::forward<CmdFunc>(cmd_func)](detail::Ring *ring) {
Expand All @@ -896,7 +903,8 @@ inline auto async_uring_cmd128(int cmd_op, Fd fd, CmdFunc &&cmd_func) {
cmd_func(sqe);
return sqe;
};
auto op = build_op_awaiter<CQEHandler>(std::move(prep_func));
auto op = build_op_awaiter<CQEHandler>(std::move(prep_func),
std::forward<Args>(handler_args)...);
return detail::maybe_flag_fixed_fd(std::move(op), fd);
}
#endif
Expand Down
38 changes: 29 additions & 9 deletions include/condy/channel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include <new>
#include <optional>
#include <type_traits>
#ifdef CONDY_HAS_STDEXEC
#include "condy/detail/execution.hpp"
#endif

namespace condy {

Expand Down Expand Up @@ -52,6 +55,11 @@ template <typename T, size_t N = 2> class Channel {

CONDY_DELETE_COPY_MOVE(Channel);

private:
class [[nodiscard]] MovePushSenderImpl;
class [[nodiscard]] CopyPushSenderImpl;
class [[nodiscard]] PopSenderImpl;

public:
/**
* @brief Try to push an item into the channel.
Expand Down Expand Up @@ -111,7 +119,11 @@ template <typename T, size_t N = 2> class Channel {
push_awaiters_.push_back(fake_handle);
}

class [[nodiscard]] MovePushSender;
#ifdef CONDY_HAS_STDEXEC
using MovePushSender = detail::StandardSender<MovePushSenderImpl>;
#else
using MovePushSender = MovePushSenderImpl;
#endif
/**
* @brief Push an item into the channel, awaiting if necessary.
* @param item The item to be pushed into the channel.
Expand All @@ -126,7 +138,11 @@ template <typename T, size_t N = 2> class Channel {
*/
MovePushSender push(T &&item) noexcept { return {*this, std::move(item)}; }

class [[nodiscard]] CopyPushSender;
#ifdef CONDY_HAS_STDEXEC
using CopyPushSender = detail::StandardSender<CopyPushSenderImpl>;
#else
using CopyPushSender = CopyPushSenderImpl;
#endif
/**
* @brief Push an item into the channel, awaiting if necessary.
* @param item The item to be pushed into the channel.
Expand All @@ -140,7 +156,11 @@ template <typename T, size_t N = 2> class Channel {
return {*this, item};
}

class [[nodiscard]] PopSender;
#ifdef CONDY_HAS_STDEXEC
using PopSender = detail::StandardSender<PopSenderImpl>;
#else
using PopSender = PopSenderImpl;
#endif
/**
* @brief Pop an item from the channel, awaiting if necessary.
* @return std::pair<int32_t, T> 0 and the popped item if successful; -EPIPE
Expand Down Expand Up @@ -529,12 +549,12 @@ class Channel<T, N>::PopFinishHandle
std::optional<StopCallbackType> stop_callback_;
};

template <typename T, size_t N> class Channel<T, N>::MovePushSender {
template <typename T, size_t N> class Channel<T, N>::MovePushSenderImpl {
public:
using CondySender = void;
using ReturnType = int32_t;

MovePushSender(Channel &channel, T &&item)
MovePushSenderImpl(Channel &channel, T &&item)
: channel_(channel), item_(std::move(item)) {}

template <typename Receiver> auto connect_impl(Receiver receiver) noexcept {
Expand Down Expand Up @@ -562,12 +582,12 @@ template <typename T, size_t N> class Channel<T, N>::MovePushSender {
T &&item_;
};

template <typename T, size_t N> class Channel<T, N>::CopyPushSender {
template <typename T, size_t N> class Channel<T, N>::CopyPushSenderImpl {
public:
using CondySender = void;
using ReturnType = int32_t;

CopyPushSender(Channel &channel, const T &item)
CopyPushSenderImpl(Channel &channel, const T &item)
: channel_(channel), item_(item) {}

template <typename Receiver> auto connect_impl(Receiver receiver) noexcept {
Expand Down Expand Up @@ -598,12 +618,12 @@ template <typename T, size_t N> class Channel<T, N>::CopyPushSender {
const T &item_;
};

template <typename T, size_t N> class Channel<T, N>::PopSender {
template <typename T, size_t N> class Channel<T, N>::PopSenderImpl {
public:
using CondySender = void;
using ReturnType = std::pair<int32_t, T>;

PopSender(Channel &channel) : channel_(channel) {}
PopSenderImpl(Channel &channel) : channel_(channel) {}

template <typename Receiver> auto connect_impl(Receiver receiver) noexcept {
return OperationState<Receiver>(channel_, std::move(receiver));
Expand Down
Loading
Loading