-
Notifications
You must be signed in to change notification settings - Fork 6
tests and more #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
tests and more #34
Changes from all commits
2a3a68d
445326f
bc40e30
ac4180d
fa821e1
f71d5b0
49b6230
142da22
e9d9abd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "version": 6, | ||
| "cmakeMinimumRequired": { | ||
| "major": 3, | ||
| "minor": 25, | ||
| "patch": 0 | ||
| }, | ||
| "configurePresets": [], | ||
| "buildPresets": [] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| // | ||
| // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com) | ||
| // | ||
| // Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
| // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
| // | ||
| // Official repository: https://github.com/cppalliance/corosio | ||
| // | ||
|
|
||
| #ifndef BOOST_COROSIO_TEST_SOCKET_PAIR_HPP | ||
| #define BOOST_COROSIO_TEST_SOCKET_PAIR_HPP | ||
|
|
||
| #include <boost/corosio/detail/config.hpp> | ||
| #include <boost/corosio/socket.hpp> | ||
|
|
||
| #include <utility> | ||
|
|
||
| namespace boost { | ||
| namespace corosio { | ||
|
|
||
| class io_context; | ||
|
|
||
| namespace test { | ||
|
|
||
| /** Create a connected pair of sockets. | ||
| Creates two sockets connected via loopback TCP sockets. | ||
| Data written to one socket can be read from the other. | ||
| @param ioc The io_context for the sockets. | ||
| @return A pair of connected sockets. | ||
| */ | ||
| BOOST_COROSIO_DECL | ||
| std::pair<socket, socket> | ||
| make_socket_pair(io_context& ioc); | ||
|
|
||
| } // namespace test | ||
| } // namespace corosio | ||
| } // namespace boost | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,7 @@ | |
| #include <boost/capy/error.hpp> | ||
| #include <boost/system/error_code.hpp> | ||
|
|
||
| #include "src/detail/make_err.hpp" | ||
| #include "src/detail/scheduler_op.hpp" | ||
|
|
||
| #include <unistd.h> | ||
|
|
@@ -62,7 +63,7 @@ struct epoll_op : scheduler_op | |
|
|
||
| int fd = -1; | ||
| std::uint32_t events = 0; | ||
| int error = 0; | ||
| int errn = 0; | ||
| std::size_t bytes_transferred = 0; | ||
|
|
||
| std::atomic<bool> cancelled{false}; | ||
|
|
@@ -77,7 +78,7 @@ struct epoll_op : scheduler_op | |
| { | ||
| fd = -1; | ||
| events = 0; | ||
| error = 0; | ||
| errn = 0; | ||
| bytes_transferred = 0; | ||
| cancelled.store(false, std::memory_order_relaxed); | ||
| } | ||
|
|
@@ -89,13 +90,13 @@ struct epoll_op : scheduler_op | |
| if (ec_out) | ||
| { | ||
| if (cancelled.load(std::memory_order_acquire)) | ||
| *ec_out = make_error_code(system::errc::operation_canceled); | ||
| else if (error != 0) | ||
| *ec_out = system::error_code(error, system::system_category()); | ||
| *ec_out = capy::error::canceled; | ||
| else if (errn != 0) | ||
| *ec_out = make_err(errn); | ||
| else if (is_read_operation() && bytes_transferred == 0) | ||
| { | ||
| // EOF: 0 bytes transferred with no error indicates end of stream | ||
| *ec_out = make_error_code(capy::error::eof); | ||
| *ec_out = capy::error::eof; | ||
| } | ||
|
Comment on lines
90
to
100
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: find . -type f -name "op.hpp" | head -20Repository: cppalliance/corosio Length of output: 100 🏁 Script executed: wc -l src/corosio/src/detail/epoll/op.hppRepository: cppalliance/corosio Length of output: 102 🏁 Script executed: sed -n '80,110p' src/corosio/src/detail/epoll/op.hppRepository: cppalliance/corosio Length of output: 883 🏁 Script executed: # Also check the broader context of the perform_io and reset methods
sed -n '1,150p' src/corosio/src/detail/epoll/op.hppRepository: cppalliance/corosio Length of output: 3683 🏁 Script executed: # Search for IOCP implementation to compare EOF handling
find . -type f -name "*.hpp" -o -name "*.h" | xargs rg -l "iocp|IOCP" | head -10Repository: cppalliance/corosio Length of output: 514 🏁 Script executed: sed -n '1,200p' src/corosio/src/detail/iocp/overlapped_op.hppRepository: cppalliance/corosio Length of output: 4334 🏁 Script executed: # Search for EOF handling in IOCP
rg -A 5 -B 5 "eof|EOF" src/corosio/src/detail/iocp/overlapped_op.hppRepository: cppalliance/corosio Length of output: 813 🏁 Script executed: # Search for empty_buffer or zero-length read handling in IOCP
rg -A 5 -B 5 "empty|buffer|bytes_transferred == 0" src/corosio/src/detail/iocp/overlapped_op.hppRepository: cppalliance/corosio Length of output: 1319 🏁 Script executed: # Find read operation implementations in epoll to see if zero-length reads can happen
find . -path "*epoll*" -name "*.hpp" -o -name "*.cpp" | xargs rg -l "is_read_operation|perform_io" | head -10Repository: cppalliance/corosio Length of output: 145 🏁 Script executed: # Check the epoll scheduler to see if empty-buffer reads are issued
sed -n '1,100p' src/corosio/src/detail/epoll/scheduler.cppRepository: cppalliance/corosio Length of output: 2379 🏁 Script executed: # Search for socket read operations in epoll
rg -A 10 "perform_io" src/corosio/src/detail/epoll/scheduler.cpp | head -50Repository: cppalliance/corosio Length of output: 313 🏁 Script executed: # Find all files in epoll directory to understand read operation implementation
find . -path "*epoll*" -type f \( -name "*.hpp" -o -name "*.cpp" \)Repository: cppalliance/corosio Length of output: 285 🏁 Script executed: # Check sockets.hpp for read operation implementations
cat -n src/corosio/src/detail/epoll/sockets.hpp | head -200Repository: cppalliance/corosio Length of output: 6816 🏁 Script executed: # Search for readv usage and iovec handling
rg -B 5 -A 10 "readv|iovec_count" src/corosio/src/detail/epoll/sockets.hppRepository: cppalliance/corosio Length of output: 1585 🏁 Script executed: # Look for the complete read operation class definition
rg -B 10 -A 20 "is_read_operation\|perform_io" src/corosio/src/detail/epoll/sockets.hpp | head -100Repository: cppalliance/corosio Length of output: 45 🏁 Script executed: # Get the complete read operation class definitions for epoll
rg -B 5 -A 30 "struct epoll_read_op|struct epoll_write_op" src/corosio/src/detail/epoll/sockets.hppRepository: cppalliance/corosio Length of output: 45 🏁 Script executed: # Check how the read_some method completes to understand the flow better
rg -B 10 -A 30 "void read_some" src/corosio/src/detail/epoll/sockets.hppRepository: cppalliance/corosio Length of output: 1014 🏁 Script executed: # Find where epoll_read_op is defined - search in all files
find . -path "*epoll*" -type f \( -name "*.hpp" -o -name "*.cpp" \) -exec grep -l "struct epoll_read_op\|class epoll_read_op" {} \;Repository: cppalliance/corosio Length of output: 100 🏁 Script executed: # Look for all operation classes across epoll files
rg "struct epoll.*_op" src/corosio/src/detail/epoll/Repository: cppalliance/corosio Length of output: 467 🏁 Script executed: # Get the full sockets.hpp file since it's not huge
wc -l src/corosio/src/detail/epoll/sockets.hppRepository: cppalliance/corosio Length of output: 107 🏁 Script executed: # Read the entire sockets.hpp file
cat src/corosio/src/detail/epoll/sockets.hppRepository: cppalliance/corosio Length of output: 14926 Add empty_buffer flag to suppress EOF for intentional empty-buffer reads on epoll. The epoll backend reports EOF (0 bytes transferred with no error) for any zero-byte read. IOCP already suppresses this for intentional empty-buffer reads via an
🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
|
|
@@ -128,7 +129,7 @@ struct epoll_op : scheduler_op | |
|
|
||
| void complete(int err, std::size_t bytes) noexcept | ||
| { | ||
| error = err; | ||
| errn = err; | ||
| bytes_transferred = bytes; | ||
| } | ||
|
|
||
|
|
@@ -170,12 +171,20 @@ struct epoll_read_op : epoll_op | |
| iovec iovecs[max_buffers]; | ||
| int iovec_count = 0; | ||
|
|
||
| bool is_read_operation() const noexcept override { return true; } | ||
| // True when 0 bytes is due to empty buffer, not EOF | ||
| bool empty_buffer_read = false; | ||
|
|
||
| // EOF only applies when we actually tried to read something | ||
| bool is_read_operation() const noexcept override | ||
| { | ||
| return !empty_buffer_read; | ||
| } | ||
|
|
||
| void reset() noexcept | ||
| { | ||
| epoll_op::reset(); | ||
| iovec_count = 0; | ||
| empty_buffer_read = false; | ||
| } | ||
|
|
||
| void perform_io() noexcept override | ||
|
|
@@ -259,14 +268,14 @@ struct epoll_accept_op : epoll_op | |
| { | ||
| stop_cb.reset(); | ||
|
|
||
| bool success = (error == 0 && !cancelled.load(std::memory_order_acquire)); | ||
| bool success = (errn == 0 && !cancelled.load(std::memory_order_acquire)); | ||
|
|
||
| if (ec_out) | ||
| { | ||
| if (cancelled.load(std::memory_order_acquire)) | ||
| *ec_out = make_error_code(system::errc::operation_canceled); | ||
| else if (error != 0) | ||
| *ec_out = system::error_code(error, system::system_category()); | ||
| *ec_out = capy::error::canceled; | ||
| else if (errn != 0) | ||
| *ec_out = make_err(errn); | ||
| } | ||
|
|
||
| if (success && accepted_fd >= 0 && peer_impl) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update the
@paramname to matchbs.The parameter was renamed to
bs(Line 81), but the doc block still usesbuffers, which can desync Doxygen-style docs.📚 Suggested doc fix
🤖 Prompt for AI Agents