From db50982efaa6094a83afd4d6729dd286e7ae4d6a Mon Sep 17 00:00:00 2001 From: Steve Gerbino Date: Thu, 5 Mar 2026 17:57:54 +0100 Subject: [PATCH] Add Javadoc documentation to all public headers Review and document every public class, struct, enum, function, type alias, and data member across 18 headers. Follows the project Javadoc conventions: /// for trivial briefs, /** */ for non-trivial, proper verb starts (Return, Construct, Check, etc.), and @see/@param where appropriate. Closes #121 --- include/boost/corosio/detail/except.hpp | 21 +++++++ include/boost/corosio/detail/scheduler.hpp | 59 ++++++++++++++---- .../boost/corosio/detail/timer_service.hpp | 36 +++++++++++ include/boost/corosio/io/io_object.hpp | 1 + include/boost/corosio/io/io_signal_set.hpp | 30 +++++++-- include/boost/corosio/io/io_timer.hpp | 15 ++++- include/boost/corosio/native/native.hpp | 7 +++ .../boost/corosio/native/native_scheduler.hpp | 11 +++- include/boost/corosio/openssl_stream.hpp | 55 ++++++++++++++++- include/boost/corosio/resolver.hpp | 8 +++ include/boost/corosio/resolver_results.hpp | 61 +++++++++++-------- include/boost/corosio/signal_set.hpp | 29 ++++++++- include/boost/corosio/tcp.hpp | 2 + include/boost/corosio/tcp_acceptor.hpp | 7 +++ include/boost/corosio/tcp_server.hpp | 16 +++++ include/boost/corosio/tcp_socket.hpp | 42 ++++++++++--- include/boost/corosio/tls_stream.hpp | 11 ++-- include/boost/corosio/wolfssl_stream.hpp | 55 ++++++++++++++++- 18 files changed, 401 insertions(+), 65 deletions(-) diff --git a/include/boost/corosio/detail/except.hpp b/include/boost/corosio/detail/except.hpp index bf783b26b..b09ff996b 100644 --- a/include/boost/corosio/detail/except.hpp +++ b/include/boost/corosio/detail/except.hpp @@ -15,12 +15,33 @@ namespace boost::corosio::detail { +/// Throw `std::logic_error` with a default message. [[noreturn]] BOOST_COROSIO_DECL void throw_logic_error(); + +/** Throw `std::logic_error` with the given message. + + @param what Null-terminated message string. + + @throws std::logic_error Always. +*/ [[noreturn]] BOOST_COROSIO_DECL void throw_logic_error(char const* what); +/** Throw `std::system_error` from @p ec. + + @param ec Error code used to construct the exception. + + @throws std::system_error Always. +*/ [[noreturn]] BOOST_COROSIO_DECL void throw_system_error(std::error_code const& ec); +/** Throw `std::system_error` from @p ec with the given context. + + @param ec Error code used to construct the exception. + @param what Null-terminated context string. + + @throws std::system_error Always. +*/ [[noreturn]] BOOST_COROSIO_DECL void throw_system_error(std::error_code const& ec, char const* what); diff --git a/include/boost/corosio/detail/scheduler.hpp b/include/boost/corosio/detail/scheduler.hpp index 0572559af..b47c1353a 100644 --- a/include/boost/corosio/detail/scheduler.hpp +++ b/include/boost/corosio/detail/scheduler.hpp @@ -20,24 +20,61 @@ namespace boost::corosio::detail { class scheduler_op; +/** Define the abstract interface for the event loop scheduler. + + Concrete backends (epoll, IOCP, kqueue, select) derive from + this to implement the reactor/proactor event loop. The + @ref io_context delegates all scheduling operations here. + + @see io_context, native_scheduler +*/ struct BOOST_COROSIO_DECL scheduler { - virtual ~scheduler() = default; + virtual ~scheduler() = default; + + /// Post a coroutine handle for deferred execution. virtual void post(std::coroutine_handle<>) const = 0; - virtual void post(scheduler_op*) const = 0; - virtual void work_started() noexcept = 0; + /// Post a scheduler operation for deferred execution. + virtual void post(scheduler_op*) const = 0; + + /// Increment the outstanding work count. + virtual void work_started() noexcept = 0; + + /// Decrement the outstanding work count. virtual void work_finished() noexcept = 0; + /// Check if the calling thread is running the event loop. virtual bool running_in_this_thread() const noexcept = 0; - virtual void stop() = 0; - virtual bool stopped() const noexcept = 0; - virtual void restart() = 0; - virtual std::size_t run() = 0; - virtual std::size_t run_one() = 0; - virtual std::size_t wait_one(long usec) = 0; - virtual std::size_t poll() = 0; - virtual std::size_t poll_one() = 0; + + /// Signal the event loop to stop. + virtual void stop() = 0; + + /// Check if the event loop has been stopped. + virtual bool stopped() const noexcept = 0; + + /// Reset the stopped state so `run()` can be called again. + virtual void restart() = 0; + + /// Run the event loop, blocking until all work completes. + virtual std::size_t run() = 0; + + /// Run one handler, blocking until one completes. + virtual std::size_t run_one() = 0; + + /** Run one handler, blocking up to @p usec microseconds. + + @param usec Maximum wait time in microseconds. + + @return The number of handlers executed (0 or 1). + */ + virtual std::size_t wait_one(long usec) = 0; + + /// Run all ready handlers without blocking. + virtual std::size_t poll() = 0; + + /// Run at most one ready handler without blocking. + virtual std::size_t poll_one() = 0; }; } // namespace boost::corosio::detail diff --git a/include/boost/corosio/detail/timer_service.hpp b/include/boost/corosio/detail/timer_service.hpp index 7855f7c6b..36a9cdba1 100644 --- a/include/boost/corosio/detail/timer_service.hpp +++ b/include/boost/corosio/detail/timer_service.hpp @@ -86,19 +86,26 @@ class BOOST_COROSIO_DECL timer_service final using clock_type = std::chrono::steady_clock; using time_point = clock_type::time_point; + /// Type-erased callback for earliest-expiry-changed notifications. class callback { void* ctx_ = nullptr; void (*fn_)(void*) = nullptr; public: + /// Construct an empty callback. callback() = default; + + /// Construct a callback with the given context and function. callback(void* ctx, void (*fn)(void*)) noexcept : ctx_(ctx), fn_(fn) {} + /// Return true if the callback is non-empty. explicit operator bool() const noexcept { return fn_ != nullptr; } + + /// Invoke the callback. void operator()() const { if (fn_) @@ -126,49 +133,78 @@ class BOOST_COROSIO_DECL timer_service final (std::numeric_limits::max)()}; public: + /// Construct the timer service bound to a scheduler. inline timer_service(capy::execution_context&, scheduler& sched) : sched_(&sched) { } + /// Return the associated scheduler. inline scheduler& get_scheduler() noexcept { return *sched_; } + /// Destroy the timer service. ~timer_service() override = default; timer_service(timer_service const&) = delete; timer_service& operator=(timer_service const&) = delete; + /// Register a callback invoked when the earliest expiry changes. inline void set_on_earliest_changed(callback cb) { on_earliest_changed_ = cb; } + /// Return true if no timers are in the heap. inline bool empty() const noexcept { return cached_nearest_ns_.load(std::memory_order_acquire) == (std::numeric_limits::max)(); } + /// Return the nearest timer expiry without acquiring the mutex. inline time_point nearest_expiry() const noexcept { auto ns = cached_nearest_ns_.load(std::memory_order_acquire); return time_point(time_point::duration(ns)); } + /// Cancel all pending timers and free cached resources. inline void shutdown() override; + + /// Construct a new timer implementation. inline io_object::implementation* construct() override; + + /// Destroy a timer implementation, cancelling pending waiters. inline void destroy(io_object::implementation* p) override; + + /// Cancel and recycle a timer implementation. inline void destroy_impl(implementation& impl); + + /// Create or recycle a waiter node. inline waiter_node* create_waiter(); + + /// Return a waiter node to the cache or free list. inline void destroy_waiter(waiter_node* w); + + /// Update the timer expiry, cancelling existing waiters. inline std::size_t update_timer(implementation& impl, time_point new_time); + + /// Insert a waiter into the timer's waiter list and the heap. inline void insert_waiter(implementation& impl, waiter_node* w); + + /// Cancel all waiters on a timer. inline std::size_t cancel_timer(implementation& impl); + + /// Cancel a single waiter ( stop_token callback path ). inline void cancel_waiter(waiter_node* w); + + /// Cancel one waiter on a timer. inline std::size_t cancel_one_waiter(implementation& impl); + + /// Complete all waiters whose timers have expired. inline std::size_t process_expired(); private: diff --git a/include/boost/corosio/io/io_object.hpp b/include/boost/corosio/io/io_object.hpp index 6dbc10a90..1cb7aaafc 100644 --- a/include/boost/corosio/io/io_object.hpp +++ b/include/boost/corosio/io/io_object.hpp @@ -223,6 +223,7 @@ class BOOST_COROSIO_DECL io_object io_object(io_object const&) = delete; io_object& operator=(io_object const&) = delete; + /// The platform I/O handle owned by this object. handle h_; }; diff --git a/include/boost/corosio/io/io_signal_set.hpp b/include/boost/corosio/io/io_signal_set.hpp index afa81607f..e45fa3136 100644 --- a/include/boost/corosio/io/io_signal_set.hpp +++ b/include/boost/corosio/io/io_signal_set.hpp @@ -68,15 +68,35 @@ class BOOST_COROSIO_DECL io_signal_set : public io_object }; public: + /** Define backend hooks for signal set wait and cancel. + + Platform backends derive from this to implement + signal delivery notification. + */ struct implementation : io_object::implementation { + /** Initiate an asynchronous wait for a signal. + + @param h Coroutine handle to resume on completion. + @param ex Executor for dispatching the completion. + @param token Stop token for cancellation. + @param ec Output error code. + @param signo Output signal number. + + @return Coroutine handle to resume immediately. + */ virtual std::coroutine_handle<> wait( - std::coroutine_handle<>, - capy::executor_ref, - std::stop_token, - std::error_code*, - int*) = 0; + std::coroutine_handle<> h, + capy::executor_ref ex, + std::stop_token token, + std::error_code* ec, + int* signo) = 0; + + /** Cancel all pending wait operations. + Cancelled waiters complete with an error that + compares equal to `capy::cond::canceled`. + */ virtual void cancel() = 0; }; diff --git a/include/boost/corosio/io/io_timer.hpp b/include/boost/corosio/io/io_timer.hpp index e9f9331e7..4527278f4 100644 --- a/include/boost/corosio/io/io_timer.hpp +++ b/include/boost/corosio/io/io_timer.hpp @@ -83,15 +83,28 @@ class BOOST_COROSIO_DECL io_timer : public io_object }; public: + /** Backend interface for timer wait operations. + + Holds per-timer state (expiry, heap position) and provides + the virtual `wait` entry point that concrete timer services + override. + */ struct implementation : io_object::implementation { + /// Sentinel value indicating the timer is not in the heap. static constexpr std::size_t npos = (std::numeric_limits::max)(); + /// The absolute expiry time point. std::chrono::steady_clock::time_point expiry_{}; - std::size_t heap_index_ = npos; + + /// Index in the timer service's min-heap, or `npos`. + std::size_t heap_index_ = npos; + + /// True if `wait()` has been called since last cancel. bool might_have_pending_waits_ = false; + /// Initiate an asynchronous wait for the timer to expire. virtual std::coroutine_handle<> wait( std::coroutine_handle<>, capy::executor_ref, diff --git a/include/boost/corosio/native/native.hpp b/include/boost/corosio/native/native.hpp index 0ff32dd80..67f82c4e4 100644 --- a/include/boost/corosio/native/native.hpp +++ b/include/boost/corosio/native/native.hpp @@ -7,6 +7,13 @@ // Official repository: https://github.com/cppalliance/corosio // +/** @file native.hpp + + Include all native (devirtualized) public headers: + I/O context, sockets, acceptor, resolver, signal set, + timer, and cancellation helpers. +*/ + #ifndef BOOST_COROSIO_NATIVE_NATIVE_HPP #define BOOST_COROSIO_NATIVE_NATIVE_HPP diff --git a/include/boost/corosio/native/native_scheduler.hpp b/include/boost/corosio/native/native_scheduler.hpp index c13ccc6fd..0e8d723b8 100644 --- a/include/boost/corosio/native/native_scheduler.hpp +++ b/include/boost/corosio/native/native_scheduler.hpp @@ -16,10 +16,17 @@ namespace boost::corosio::detail { class timer_service; -// Intermediary between public scheduler and concrete backends, -// holds cached service pointers behind the compilation firewall +/** Cache service pointers for native backend schedulers. + + Sits between @ref scheduler and the concrete backend schedulers, + storing service pointers that would otherwise require a virtual + call or service lookup on every timer operation. + + @see scheduler +*/ struct native_scheduler : scheduler { + /// Store the timer service pointer, set during construction. timer_service* timer_svc_ = nullptr; }; diff --git a/include/boost/corosio/openssl_stream.hpp b/include/boost/corosio/openssl_stream.hpp index 10c21067d..f7ad223ac 100644 --- a/include/boost/corosio/openssl_stream.hpp +++ b/include/boost/corosio/openssl_stream.hpp @@ -114,25 +114,76 @@ class BOOST_COROSIO_DECL openssl_stream final : public tls_stream */ ~openssl_stream() override; - openssl_stream(openssl_stream&&) noexcept; - openssl_stream& operator=(openssl_stream&&) noexcept; + /** Move construct from another OpenSSL stream. + @param other The source stream. After the move, + @p other is in a valid but unspecified state. + */ + openssl_stream(openssl_stream&& other) noexcept; + + /** Move assign from another OpenSSL stream. + + @param other The source stream. After the move, + @p other is in a valid but unspecified state. + + @return `*this`. + */ + openssl_stream& operator=(openssl_stream&& other) noexcept; + + /** Perform the TLS handshake asynchronously. + + Suspends the calling coroutine until the handshake + completes, an error occurs, or the operation is + cancelled via stop token. + + @par Preconditions + The underlying stream must be connected. No other + TLS operation may be in progress on this stream. + + @param type The handshake role (client or server). + + @return An awaitable yielding `(error_code)`. + */ capy::io_task<> handshake(handshake_type type) override; + /** Shut down the TLS session asynchronously. + + Sends a close_notify alert and waits for the peer's + close_notify response. Supports cancellation via + stop token. + + @par Preconditions + A handshake must have completed successfully. No + other TLS operation may be in progress on this stream. + + @return An awaitable yielding `(error_code)`. + */ capy::io_task<> shutdown() override; + /** Reset TLS session state for reuse. + + Clears internal buffers and session data so the stream + can perform a new handshake on the same underlying + connection. + + @par Preconditions + No TLS operation may be in progress on this stream. + */ void reset() override; + /// Return the underlying stream. capy::any_stream& next_layer() noexcept override { return stream_; } + /// Return the underlying stream. capy::any_stream const& next_layer() const noexcept override { return stream_; } + /// Return the TLS backend name ("openssl"). std::string_view name() const noexcept override; protected: diff --git a/include/boost/corosio/resolver.hpp b/include/boost/corosio/resolver.hpp index ac9465bbd..ad27a7ec5 100644 --- a/include/boost/corosio/resolver.hpp +++ b/include/boost/corosio/resolver.hpp @@ -433,8 +433,14 @@ class BOOST_COROSIO_DECL resolver : public io_object void cancel(); public: + /** Backend interface for DNS resolution operations. + + Platform backends derive from this to implement forward and + reverse DNS resolution via getaddrinfo/getnameinfo. + */ struct implementation : io_object::implementation { + /// Initiate an asynchronous forward DNS resolution. virtual std::coroutine_handle<> resolve( std::coroutine_handle<>, capy::executor_ref, @@ -445,6 +451,7 @@ class BOOST_COROSIO_DECL resolver : public io_object std::error_code*, resolver_results*) = 0; + /// Initiate an asynchronous reverse DNS resolution. virtual std::coroutine_handle<> reverse_resolve( std::coroutine_handle<>, capy::executor_ref, @@ -454,6 +461,7 @@ class BOOST_COROSIO_DECL resolver : public io_object std::error_code*, reverse_resolver_result*) = 0; + /// Cancel pending resolve operations. virtual void cancel() noexcept = 0; }; diff --git a/include/boost/corosio/resolver_results.hpp b/include/boost/corosio/resolver_results.hpp index 22097d1aa..e3d744d23 100644 --- a/include/boost/corosio/resolver_results.hpp +++ b/include/boost/corosio/resolver_results.hpp @@ -37,7 +37,7 @@ class resolver_entry std::string service_name_; public: - /** Default constructor. */ + /// Construct a default empty entry. resolver_entry() = default; /** Construct with endpoint, host name, and service name. @@ -53,25 +53,25 @@ class resolver_entry { } - /** Get the endpoint. */ + /// Return the resolved endpoint. endpoint get_endpoint() const noexcept { return ep_; } - /** Implicit conversion to endpoint. */ + /// Convert to endpoint. operator endpoint() const noexcept { return ep_; } - /** Get the host name from the query. */ + /// Return the host name from the query. std::string const& host_name() const noexcept { return host_name_; } - /** Get the service name from the query. */ + /// Return the service name from the query. std::string const& service_name() const noexcept { return service_name_; @@ -91,19 +91,32 @@ class resolver_entry class resolver_results { public: - using value_type = resolver_entry; + /// The entry type. + using value_type = resolver_entry; + + /// Const reference to an entry. using const_reference = value_type const&; - using reference = const_reference; - using const_iterator = std::vector::const_iterator; - using iterator = const_iterator; + + /// Reference to an entry (always const). + using reference = const_reference; + + /// Const iterator over entries. + using const_iterator = std::vector::const_iterator; + + /// Iterator over entries (always const). + using iterator = const_iterator; + + /// Signed difference type. using difference_type = std::ptrdiff_t; - using size_type = std::size_t; + + /// Unsigned size type. + using size_type = std::size_t; private: std::shared_ptr> entries_; public: - /** Default constructor creates an empty range. */ + /// Construct an empty results range. resolver_results() = default; /** Construct from a vector of entries. @@ -116,19 +129,19 @@ class resolver_results { } - /** Get the number of entries. */ + /// Return the number of entries. size_type size() const noexcept { return entries_ ? entries_->size() : 0; } - /** Check if the results are empty. */ + /// Check if the results are empty. bool empty() const noexcept { return !entries_ || entries_->empty(); } - /** Get an iterator to the first entry. */ + /// Return an iterator to the first entry. const_iterator begin() const noexcept { if (entries_) @@ -136,7 +149,7 @@ class resolver_results return std::vector::const_iterator(); } - /** Get an iterator past the last entry. */ + /// Return an iterator past the last entry. const_iterator end() const noexcept { if (entries_) @@ -144,32 +157,32 @@ class resolver_results return std::vector::const_iterator(); } - /** Get an iterator to the first entry. */ + /// Return an iterator to the first entry. const_iterator cbegin() const noexcept { return begin(); } - /** Get an iterator past the last entry. */ + /// Return an iterator past the last entry. const_iterator cend() const noexcept { return end(); } - /** Swap with another results object. */ + /// Swap with another results object. void swap(resolver_results& other) noexcept { entries_.swap(other.entries_); } - /** Test for equality. */ + /// Test for equality. friend bool operator==(resolver_results const& a, resolver_results const& b) noexcept { return a.entries_ == b.entries_; } - /** Test for inequality. */ + /// Test for inequality. friend bool operator!=(resolver_results const& a, resolver_results const& b) noexcept { @@ -193,7 +206,7 @@ class reverse_resolver_result std::string service_; public: - /** Default constructor. */ + /// Construct a default empty result. reverse_resolver_result() = default; /** Construct with endpoint, host name, and service name. @@ -210,19 +223,19 @@ class reverse_resolver_result { } - /** Get the endpoint that was resolved. */ + /// Return the endpoint that was resolved. corosio::endpoint endpoint() const noexcept { return ep_; } - /** Get the resolved host name. */ + /// Return the resolved host name. std::string const& host_name() const noexcept { return host_; } - /** Get the resolved service name. */ + /// Return the resolved service name. std::string const& service_name() const noexcept { return service_; diff --git a/include/boost/corosio/signal_set.hpp b/include/boost/corosio/signal_set.hpp index 53b99ca7e..7a412f89e 100644 --- a/include/boost/corosio/signal_set.hpp +++ b/include/boost/corosio/signal_set.hpp @@ -160,11 +160,36 @@ class BOOST_COROSIO_DECL signal_set : public io_signal_set return static_cast(~static_cast(a)); } + /** Define backend hooks for signal set operations. + + Platform backends derive from this to provide signal + registration via sigaction (POSIX) or the C runtime + signal() function (Windows). + */ struct implementation : io_signal_set::implementation { + /** Register a signal with the given flags. + + @param signal_number The signal to register. + @param flags Platform-specific signal handling flags. + + @return Error code on failure, empty on success. + */ virtual std::error_code add(int signal_number, flags_t flags) = 0; - virtual std::error_code remove(int signal_number) = 0; - virtual std::error_code clear() = 0; + + /** Unregister a signal. + + @param signal_number The signal to remove. + + @return Error code on failure, empty on success. + */ + virtual std::error_code remove(int signal_number) = 0; + + /** Unregister all signals. + + @return Error code on failure, empty on success. + */ + virtual std::error_code clear() = 0; }; /** Destructor. diff --git a/include/boost/corosio/tcp.hpp b/include/boost/corosio/tcp.hpp index 711ac2c63..cfb53965d 100644 --- a/include/boost/corosio/tcp.hpp +++ b/include/boost/corosio/tcp.hpp @@ -78,11 +78,13 @@ class BOOST_COROSIO_DECL tcp /// The associated acceptor type. using acceptor = tcp_acceptor; + /// Test for equality. friend constexpr bool operator==(tcp a, tcp b) noexcept { return a.v6_ == b.v6_; } + /// Test for inequality. friend constexpr bool operator!=(tcp a, tcp b) noexcept { return a.v6_ != b.v6_; diff --git a/include/boost/corosio/tcp_acceptor.hpp b/include/boost/corosio/tcp_acceptor.hpp index 702543e13..04374ece8 100644 --- a/include/boost/corosio/tcp_acceptor.hpp +++ b/include/boost/corosio/tcp_acceptor.hpp @@ -416,8 +416,15 @@ class BOOST_COROSIO_DECL tcp_acceptor : public io_object return opt; } + /** Define backend hooks for TCP acceptor operations. + + Platform backends derive from this to implement + accept, endpoint query, open-state checks, cancellation, + and socket-option management. + */ struct implementation : io_object::implementation { + /// Initiate an asynchronous accept operation. virtual std::coroutine_handle<> accept( std::coroutine_handle<>, capy::executor_ref, diff --git a/include/boost/corosio/tcp_server.hpp b/include/boost/corosio/tcp_server.hpp index 8c14ade4b..032c6d9a3 100644 --- a/include/boost/corosio/tcp_server.hpp +++ b/include/boost/corosio/tcp_server.hpp @@ -598,10 +598,26 @@ class BOOST_COROSIO_DECL tcp_server } public: + /// Destroy the server, stopping all accept loops. ~tcp_server(); + tcp_server(tcp_server const&) = delete; tcp_server& operator=(tcp_server const&) = delete; + + /** Move construct from another server. + + @param o The source server. After the move, @p o is + in a valid but unspecified state. + */ tcp_server(tcp_server&& o) noexcept; + + /** Move assign from another server. + + @param o The source server. After the move, @p o is + in a valid but unspecified state. + + @return `*this`. + */ tcp_server& operator=(tcp_server&& o) noexcept; /** Bind to a local endpoint. diff --git a/include/boost/corosio/tcp_socket.hpp b/include/boost/corosio/tcp_socket.hpp index e67ca7026..89a32a7b8 100644 --- a/include/boost/corosio/tcp_socket.hpp +++ b/include/boost/corosio/tcp_socket.hpp @@ -34,8 +34,9 @@ namespace boost::corosio { +/// Represent a platform-specific socket descriptor (`int` on POSIX, `SOCKET` on Windows). #if BOOST_COROSIO_HAS_IOCP && !defined(BOOST_COROSIO_MRDOCS) -using native_handle_type = std::uintptr_t; // SOCKET +using native_handle_type = std::uintptr_t; #else using native_handle_type = int; #endif @@ -89,17 +90,39 @@ class BOOST_COROSIO_DECL tcp_socket : public io_stream shutdown_both }; + /** Define backend hooks for TCP socket operations. + + Platform backends (epoll, IOCP, kqueue, select) derive from + this to implement socket I/O, connection, and option management. + */ struct implementation : io_stream::implementation { + /** Initiate an asynchronous connect to the given endpoint. + + @param h Coroutine handle to resume on completion. + @param ex Executor for dispatching the completion. + @param ep The remote endpoint to connect to. + @param token Stop token for cancellation. + @param ec Output error code. + + @return Coroutine handle to resume immediately. + */ virtual std::coroutine_handle<> connect( - std::coroutine_handle<>, - capy::executor_ref, - endpoint, - std::stop_token, - std::error_code*) = 0; + std::coroutine_handle<> h, + capy::executor_ref ex, + endpoint ep, + std::stop_token token, + std::error_code* ec) = 0; - virtual std::error_code shutdown(shutdown_type) noexcept = 0; + /** Shut down the socket for the given direction(s). + + @param what The shutdown direction. + + @return Error code on failure, empty on success. + */ + virtual std::error_code shutdown(shutdown_type what) noexcept = 0; + /// Return the platform socket descriptor. virtual native_handle_type native_handle() const noexcept = 0; /** Request cancellation of pending asynchronous operations. @@ -136,13 +159,14 @@ class BOOST_COROSIO_DECL tcp_socket : public io_stream get_option(int level, int optname, void* data, std::size_t* size) const noexcept = 0; - /// Returns the cached local endpoint. + /// Return the cached local endpoint. virtual endpoint local_endpoint() const noexcept = 0; - /// Returns the cached remote endpoint. + /// Return the cached remote endpoint. virtual endpoint remote_endpoint() const noexcept = 0; }; + /// Represent the awaitable returned by @ref connect. struct connect_awaitable { tcp_socket& s_; diff --git a/include/boost/corosio/tls_stream.hpp b/include/boost/corosio/tls_stream.hpp index c092dbc37..38b83504a 100644 --- a/include/boost/corosio/tls_stream.hpp +++ b/include/boost/corosio/tls_stream.hpp @@ -46,17 +46,14 @@ namespace boost::corosio { class BOOST_COROSIO_DECL tls_stream { public: - /** Different handshake types. */ + /// Identify the TLS handshake role. enum handshake_type { - /** Perform handshaking as a client. */ - client, - - /** Perform handshaking as a server. */ - server + client, ///< Perform handshaking as a client. + server ///< Perform handshaking as a server. }; - /** Destructor. */ + /// Destroy the TLS stream. virtual ~tls_stream() = default; tls_stream(tls_stream const&) = delete; diff --git a/include/boost/corosio/wolfssl_stream.hpp b/include/boost/corosio/wolfssl_stream.hpp index 6f8eab9cf..3ea25370c 100644 --- a/include/boost/corosio/wolfssl_stream.hpp +++ b/include/boost/corosio/wolfssl_stream.hpp @@ -114,25 +114,76 @@ class BOOST_COROSIO_DECL wolfssl_stream final : public tls_stream */ ~wolfssl_stream() override; - wolfssl_stream(wolfssl_stream&&) noexcept; - wolfssl_stream& operator=(wolfssl_stream&&) noexcept; + /** Move construct from another WolfSSL stream. + @param other The source stream. After the move, + @p other is in a valid but unspecified state. + */ + wolfssl_stream(wolfssl_stream&& other) noexcept; + + /** Move assign from another WolfSSL stream. + + @param other The source stream. After the move, + @p other is in a valid but unspecified state. + + @return `*this`. + */ + wolfssl_stream& operator=(wolfssl_stream&& other) noexcept; + + /** Perform the TLS handshake asynchronously. + + Suspends the calling coroutine until the handshake + completes, an error occurs, or the operation is + cancelled via stop token. + + @par Preconditions + The underlying stream must be connected. No other + TLS operation may be in progress on this stream. + + @param type The handshake role (client or server). + + @return An awaitable yielding `(error_code)`. + */ capy::io_task<> handshake(handshake_type type) override; + /** Shut down the TLS session asynchronously. + + Sends a close_notify alert and waits for the peer's + close_notify response. Supports cancellation via + stop token. + + @par Preconditions + A handshake must have completed successfully. No + other TLS operation may be in progress on this stream. + + @return An awaitable yielding `(error_code)`. + */ capy::io_task<> shutdown() override; + /** Reset TLS session state for reuse. + + Clears internal buffers and session data so the stream + can perform a new handshake on the same underlying + connection. + + @par Preconditions + No TLS operation may be in progress on this stream. + */ void reset() override; + /// Return the underlying stream. capy::any_stream& next_layer() noexcept override { return stream_; } + /// Return the underlying stream. capy::any_stream const& next_layer() const noexcept override { return stream_; } + /// Return the TLS backend name ("wolfssl"). std::string_view name() const noexcept override; protected: