diff --git a/CMakeLists.txt b/CMakeLists.txt index e122fd3..a114e59 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,11 +26,11 @@ set(test_dir "${CMAKE_SOURCE_DIR}/test") set(include_dir "${CMAKE_SOURCE_DIR}/include") set(submodules_dir "${CMAKE_SOURCE_DIR}/submodules") +set(CXX_FLAG_SET "") if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # Disable PSABI warnings in GCC (on RPi). list(APPEND CXX_FLAG_SET "-Wno-psabi") endif() - add_compile_options("$<$:${CXX_FLAG_SET}>") # clang-format diff --git a/CMakePresets.json b/CMakePresets.json index 434904a..e77475b 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -75,11 +75,6 @@ "cacheVariables": { "CMAKE_C_COMPILER": "clang", "CMAKE_CXX_COMPILER": "clang++" - }, - "vendor": { - "jetbrains.com/clion": { - "toolchain": "Clang19" - } } } ], diff --git a/include/ocvsmd/platform/bsd/kqueue_single_threaded_executor.hpp b/include/ocvsmd/platform/bsd/kqueue_single_threaded_executor.hpp index a59489d..473e071 100644 --- a/include/ocvsmd/platform/bsd/kqueue_single_threaded_executor.hpp +++ b/include/ocvsmd/platform/bsd/kqueue_single_threaded_executor.hpp @@ -108,6 +108,12 @@ class KqueueSingleThreadedExecutor final : public libcyphal::platform::SingleThr if (kqueue_result < 0) { const auto err = errno; + if (err == EINTR) + { + // Normally, we would just retry a system call (`::kevent`), + // but we need updated timeout (from the main loop). + return cetl::nullopt; + } return libcyphal::transport::PlatformError{PosixPlatformError{err}}; } if (kqueue_result == 0) @@ -185,7 +191,7 @@ class KqueueSingleThreadedExecutor final : public libcyphal::platform::SingleThr AwaitableNode(Self& executor, Callback::Function&& function) : CallbackNode{executor, std::move(function)} , fd_{-1} - , events_{0} + , filter_{0} { } @@ -194,7 +200,7 @@ class KqueueSingleThreadedExecutor final : public libcyphal::platform::SingleThr if (fd_ >= 0) { KEvent ev{}; - EV_SET(&ev, fd_, events_, EV_DELETE, NOTE_DELETE, 0, 0); + EV_SET(&ev, fd_, filter_, EV_DELETE, 0, 0, 0); ::kevent(getExecutor().kqueuefd_, &ev, 1, nullptr, 0, nullptr); getExecutor().total_awaitables_--; } @@ -203,14 +209,14 @@ class KqueueSingleThreadedExecutor final : public libcyphal::platform::SingleThr AwaitableNode(AwaitableNode&& other) noexcept : CallbackNode(std::move(static_cast(other))) , fd_{std::exchange(other.fd_, -1)} - , events_{std::exchange(other.events_, 0)} + , filter_{std::exchange(other.filter_, 0)} { if (fd_ >= 0) { KEvent ev{}; - EV_SET(&ev, fd_, events_, EV_DELETE, NOTE_DELETE, 0, 0); + EV_SET(&ev, fd_, filter_, EV_DELETE, 0, 0, 0); ::kevent(getExecutor().kqueuefd_, &ev, 1, nullptr, 0, nullptr); - EV_SET(&ev, fd_, events_, EV_ADD | EV_CLEAR, NOTE_WRITE, 0, this); + EV_SET(&ev, fd_, filter_, EV_ADD, 0, 0, this); ::kevent(getExecutor().kqueuefd_, &ev, 1, nullptr, 0, nullptr); } } @@ -224,22 +230,22 @@ class KqueueSingleThreadedExecutor final : public libcyphal::platform::SingleThr return fd_; } - std::uint32_t events() const noexcept + std::int16_t filter() const noexcept { - return events_; + return filter_; } - void setup(const int fd, const std::uint32_t events) noexcept + void setup(const int fd, const std::int16_t filter) noexcept { CETL_DEBUG_ASSERT(fd >= 0, ""); - CETL_DEBUG_ASSERT(events != 0, ""); + CETL_DEBUG_ASSERT(filter != 0, ""); fd_ = fd; - events_ = events | EVFILT_VNODE; + filter_ = filter; getExecutor().total_awaitables_++; KEvent ev{}; - EV_SET(&ev, fd, events_, EV_ADD | EV_CLEAR, NOTE_WRITE, 0, this); + EV_SET(&ev, fd, filter_, EV_ADD, 0, 0, this); ::kevent(getExecutor().kqueuefd_, &ev, 1, nullptr, 0, nullptr); } @@ -253,8 +259,8 @@ class KqueueSingleThreadedExecutor final : public libcyphal::platform::SingleThr // MARK: Data members: - int fd_; - std::uint32_t events_; + int fd_; + std::int16_t filter_; }; // AwaitableNode diff --git a/include/ocvsmd/platform/linux/epoll_single_threaded_executor.hpp b/include/ocvsmd/platform/linux/epoll_single_threaded_executor.hpp index fe9a525..e54c137 100644 --- a/include/ocvsmd/platform/linux/epoll_single_threaded_executor.hpp +++ b/include/ocvsmd/platform/linux/epoll_single_threaded_executor.hpp @@ -99,6 +99,12 @@ class EpollSingleThreadedExecutor final : public libcyphal::platform::SingleThre if (epoll_result < 0) { const auto err = errno; + if (err == EINTR) + { + // Normally, we would just retry a system call (`::epoll_wait`), + // but we need updated timeout (from the main loop). + return cetl::nullopt; + } return libcyphal::transport::PlatformError{PosixPlatformError{err}}; } if (epoll_result == 0) diff --git a/src/daemon/engine/CMakeLists.txt b/src/daemon/engine/CMakeLists.txt index 0bb5371..8eaea87 100644 --- a/src/daemon/engine/CMakeLists.txt +++ b/src/daemon/engine/CMakeLists.txt @@ -47,7 +47,6 @@ add_library(ocvsmd_engine config.cpp cyphal/file_provider.cpp engine.cpp - platform/can/socketcan.c platform/udp/udp.c svc/file_server/list_roots_service.cpp svc/file_server/pop_root_service.cpp @@ -62,6 +61,11 @@ target_link_libraries(ocvsmd_engine PUBLIC ${engine_transpiled} PUBLIC ocvsmd_common ) +if (${PLATFORM_OS_TYPE} STREQUAL "linux") + target_sources(ocvsmd_engine + PRIVATE platform/can/socketcan.c + ) +endif () target_include_directories(ocvsmd_engine PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/src/daemon/engine/cyphal/transport_helpers.hpp b/src/daemon/engine/cyphal/transport_helpers.hpp index ba5f53c..3a0f771 100644 --- a/src/daemon/engine/cyphal/transport_helpers.hpp +++ b/src/daemon/engine/cyphal/transport_helpers.hpp @@ -61,6 +61,8 @@ struct TransportHelpers }; // Printers +#ifdef __linux__ + struct CanTransientErrorReporter { using Report = libcyphal::transport::can::ICanTransport::TransientErrorReport; @@ -111,6 +113,8 @@ struct TransportHelpers }; // CanTransientErrorReporter +#endif // __linux__ + struct UdpTransientErrorReporter { using Report = libcyphal::transport::udp::IUdpTransport::TransientErrorReport; diff --git a/src/daemon/engine/engine.cpp b/src/daemon/engine/engine.cpp index 1449b8f..96db3de 100644 --- a/src/daemon/engine/engine.cpp +++ b/src/daemon/engine/engine.cpp @@ -59,11 +59,13 @@ cetl::optional Engine::init() } else { +#ifdef __linux__ if (auto maybe_can_transport_bag = cyphal::CanTransportBag::make(memory_, executor_, config_)) { any_transport_bag_ = std::move(maybe_can_transport_bag); } else +#endif // __linux__ { std::string msg = "Failed to create Cyphal transport."; logger_->error(msg);