@@ -53,13 +53,14 @@ namespace coio {
5353
5454 class io_object {
5555 public:
56- io_object (uring_context& ctx, int fd) noexcept : ctx_(&ctx), fd_(fd) {}
56+ io_object (uring_context& ctx, int fd);
5757
5858 io_object (const io_object&) = delete ;
5959
6060 io_object (io_object&& other) noexcept :
6161 ctx_ (other.ctx_),
62- fd_ (std::exchange(other.fd_, -1 )) {}
62+ fd_ (std::exchange(other.fd_, -1 )),
63+ stream_oriented_ (std::exchange(other.stream_oriented_, false )) {}
6364
6465 ~io_object ();
6566
@@ -71,6 +72,7 @@ namespace coio {
7172 auto swap (io_object& other) noexcept -> void {
7273 std::ranges::swap (ctx_, other.ctx_ );
7374 std::ranges::swap (fd_, other.fd_ );
75+ std::ranges::swap (stream_oriented_, other.stream_oriented_ );
7476 }
7577
7678 friend auto swap (io_object& lhs, io_object& rhs) noexcept -> void {
@@ -104,6 +106,11 @@ namespace coio {
104106 [[nodiscard]]
105107 auto send_to (std::span<const std::byte> buffer, const endpoint& dest) -> std::size_t;
106108
109+ auto connect (const endpoint& peer) -> void;
110+
111+ [[nodiscard]]
112+ auto accept () -> detail::socket_native_handle_type;
113+
107114 auto read_some (std::span<std::byte> buffer) -> std::size_t;
108115
109116 auto write_some (std::span<const std::byte> buffer) -> std::size_t;
@@ -130,7 +137,7 @@ namespace coio {
130137 public:
131138 [[nodiscard]]
132139 COIO_ALWAYS_INLINE auto async_receive (std::span<std::byte> buffer) noexcept {
133- return async_initiate<detail::receive_tag>(buffer);
140+ return async_initiate<detail::receive_tag>(buffer, stream_oriented_ );
134141 }
135142
136143 [[nodiscard]]
@@ -181,6 +188,7 @@ namespace coio {
181188 private:
182189 uring_context* ctx_;
183190 int fd_ = -1 ;
191+ bool stream_oriented_ = false ;
184192 };
185193
186194 template <typename Tag, typename ... Args>
@@ -243,9 +251,7 @@ namespace coio {
243251 using scheduler_base::scheduler_base;
244252
245253 [[nodiscard]]
246- COIO_ALWAYS_INLINE auto make_io_object (int fd) const -> io_object {
247- return io_object{*ctx_, fd};
248- }
254+ auto make_io_object (int fd) const -> io_object ;
249255 };
250256
251257 template <typename T = void , typename Alloc = void >
@@ -291,14 +297,27 @@ namespace coio {
291297 public:
292298 uring_node_for (int fd, uring_context& context) noexcept : uring_node(context, fd) {}
293299
300+ protected:
294301 auto do_start () noexcept -> start_result {
302+ if (fd == -1 ) [[unlikely]] {
303+ result.set_error (std::make_error_code (std::errc::bad_file_descriptor));
304+ return start_result::completed;
305+ }
306+
307+ auto derived = static_cast <uring_state_base_for<Tag>*>(this );
308+ if constexpr (requires { derived->try_complete (); }) {
309+ if (derived->try_complete ()) {
310+ return start_result::completed;
311+ }
312+ }
313+
295314 std::scoped_lock _{context_.uring_mtx_ };
296315 auto sqe = context_.allocate_sqe ();
297316 if (sqe == nullptr ) {
298317 result.set_error (std::make_error_code (std::errc::no_buffer_space));
299318 return start_result::completed;
300319 }
301- static_cast <uring_state_base_for<Tag>*>( this ) ->prepare (sqe);
320+ derived ->prepare (sqe);
302321 ::io_uring_sqe_set_data (sqe, static_cast <uring_node*>(this ));
303322 // TODO: To suppress TSAN false positives, we need to add more TSAN annotations! see https://github.com/axboe/liburing/issues/1514
304323 COIO_TSAN_RELEASE (static_cast <uring_node*>(this ));
@@ -355,6 +374,9 @@ namespace coio {
355374
356375 auto prepare (::io_uring_sqe* sqe) noexcept -> void;
357376
377+ private:
378+ auto complete (int cqe_res) noexcept -> void override ;
379+
358380 private:
359381 std::span<std::byte> buffer_;
360382 };
@@ -386,6 +408,9 @@ namespace coio {
386408
387409 auto prepare (::io_uring_sqe* sqe) noexcept -> void;
388410
411+ private:
412+ auto complete (int cqe_res) noexcept -> void override ;
413+
389414 private:
390415 std::size_t offset_;
391416 std::span<std::byte> buffer_;
@@ -413,14 +438,21 @@ namespace coio {
413438 template <>
414439 class uring_state_base_for <receive_tag> : public uring_node_for<receive_tag> {
415440 public:
416- uring_state_base_for (int fd, uring_context& context, std::span<std::byte> buffer) noexcept :
441+ uring_state_base_for (int fd, uring_context& context, std::span<std::byte> buffer, bool stream_oriented ) noexcept :
417442 uring_node_for (fd, context),
418- buffer_ (buffer) {}
443+ buffer_ (buffer),
444+ stream_oriented_ (stream_oriented) {}
419445
420446 auto prepare (::io_uring_sqe* sqe) noexcept -> void;
421447
448+ auto try_complete () noexcept -> bool;
449+
450+ private:
451+ auto complete (int cqe_res) noexcept -> void override ;
452+
422453 private:
423454 std::span<std::byte> buffer_;
455+ bool stream_oriented_;
424456 };
425457
426458
0 commit comments