@@ -136,6 +136,45 @@ class BOOST_COROSIO_DECL tcp_acceptor : public io_object
136136 }
137137 };
138138
139+ struct accept_value_awaitable
140+ {
141+ tcp_acceptor& acc_;
142+ tcp_socket peer_;
143+ std::stop_token token_;
144+ mutable std::error_code ec_;
145+ mutable io_object::implementation* peer_impl_ = nullptr ;
146+
147+ explicit accept_value_awaitable (tcp_acceptor& acc)
148+ : acc_(acc)
149+ , peer_(acc.context())
150+ {
151+ }
152+
153+ bool await_ready () const noexcept
154+ {
155+ return token_.stop_requested ();
156+ }
157+
158+ capy::io_result<tcp_socket> await_resume () noexcept
159+ {
160+ if (token_.stop_requested ())
161+ return {make_error_code (std::errc::operation_canceled),
162+ std::move (peer_)};
163+
164+ if (!ec_ && peer_impl_)
165+ peer_.h_ .reset (peer_impl_);
166+ return {ec_, std::move (peer_)};
167+ }
168+
169+ auto await_suspend (std::coroutine_handle<> h, capy::io_env const * env)
170+ -> std::coroutine_handle<>
171+ {
172+ token_ = env->stop_token ;
173+ return acc_.get ().accept (
174+ h, env->executor , token_, &ec_, &peer_impl_);
175+ }
176+ };
177+
139178public:
140179 /* * Destructor.
141180
@@ -341,6 +380,8 @@ class BOOST_COROSIO_DECL tcp_acceptor : public io_object
341380 // Use peer socket
342381 }
343382 @endcode
383+
384+ @see accept()
344385 */
345386 auto accept (tcp_socket& peer)
346387 {
@@ -349,6 +390,48 @@ class BOOST_COROSIO_DECL tcp_acceptor : public io_object
349390 return accept_awaitable (*this , peer);
350391 }
351392
393+ /* * Initiate an asynchronous accept operation, returning the peer.
394+
395+ Accepts an incoming connection and returns a newly constructed
396+ socket for it, associated with this acceptor's execution context.
397+ The acceptor must be listening before calling this function.
398+
399+ The caller does not pre-construct the peer socket; the returned
400+ socket shares this acceptor's execution context.
401+
402+ The operation supports cancellation via `std::stop_token` through
403+ the affine awaitable protocol. If the associated stop token is
404+ triggered, the operation completes immediately with
405+ `errc::operation_canceled`.
406+
407+ @return An awaitable that completes with `io_result<tcp_socket>`.
408+ On success the payload is the connected peer socket; on failure
409+ (including cancellation) the error code is set and the payload
410+ socket is unconnected. Errors include:
411+ - operation_canceled: Cancelled via stop_token or cancel().
412+ Check `ec == cond::canceled` for portable comparison.
413+
414+ @par Preconditions
415+ The acceptor must be listening (`is_open() == true`). This acceptor
416+ must outlive the returned awaitable.
417+
418+ @par Example
419+ @code
420+ auto [ec, peer] = co_await acc.accept();
421+ if (!ec) {
422+ // peer is a connected socket
423+ }
424+ @endcode
425+
426+ @see accept(tcp_socket&)
427+ */
428+ auto accept ()
429+ {
430+ if (!is_open ())
431+ detail::throw_logic_error (" accept: acceptor not listening" );
432+ return accept_value_awaitable (*this );
433+ }
434+
352435 /* * Wait for an incoming connection or readiness condition.
353436
354437 Suspends until the listen socket is ready in the
0 commit comments