Removes platform dependent macro pollution#88
Conversation
📝 WalkthroughWalkthroughAdds a platform feature-detection header exposing BOOST_COROSIO_HAS_IOCP/EPOLL/KQUEUE/SELECT and BOOST_COROSIO_POSIX, replaces OS-specific preprocessor guards across the codebase with these macros, and introduces/rewires select- and epoll-based acceptor implementations plus per-op cancellation semantics. Changes
Sequence Diagram(s)sequenceDiagram
participant App as Acceptor (user)
participant AcceptorSvc as Acceptors (epoll/select acceptor_service)
participant Scheduler as Scheduler (epoll_scheduler / select_scheduler)
participant Reactor as Kernel Reactor (epoll/select)
participant SocketSvc as Socket Service
participant Coroutine as Coroutine (awaiter)
App->>AcceptorSvc: open_acceptor(bind, backlog)
AcceptorSvc->>Scheduler: register fd for read
note right of Scheduler: Scheduler integrates with Reactor
Coroutine->>AcceptorSvc: async accept (co_await)
AcceptorSvc->>Reactor: ensure fd monitored
Reactor-->>Scheduler: readiness event (EPOLLIN/FD_SET)
Scheduler->>AcceptorSvc: dispatch accept_op (op->operator())
AcceptorSvc->>SocketSvc: create peer socket_impl
AcceptorSvc->>AcceptorSvc: set endpoints, finalize
AcceptorSvc->>Coroutine: resume with accepted socket / error
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Comment |
|
An automated preview of the documentation is available at https://88.corosio.prtest3.cppalliance.org/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-01-28 17:18:20 UTC |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/corosio/src/detail/iocp/timers.cpp (1)
11-18: Add a brief implementation overview block after the includes.This file contains backend-selection logic (NT timers first, thread fallback) but lacks the required high-level /* */ overview immediately after the includes.
📝 Suggested addition
`#include` "src/detail/iocp/timers.hpp" `#include` "src/detail/iocp/timers_nt.hpp" `#include` "src/detail/iocp/timers_thread.hpp" +/* + Overview: prefer the NT timer backend when available; otherwise + fall back to a dedicated thread-based timer implementation. +*/ namespace boost::corosio::detail {As per coding guidelines: Files containing non-trivial implementation logic should include a
/* */block comment after the includes that provides a high-level overview of how the implementation works.
🧹 Nitpick comments (4)
src/corosio/src/select_context.cpp (1)
10-17: Missing explicitplatform.hppinclude before using the feature macro.
BOOST_COROSIO_HAS_SELECTis used at line 13, butplatform.hppis not explicitly included in this file. The code relies onselect_context.hppto transitively includeplatform.hpp. This implicit dependency can break if header inclusion order changes or ifselect_context.hppis refactored.Other files in this PR (e.g.,
timers_thread.cpp,resolver_service.hpp) explicitly includeplatform.hppbefore using the feature macros.Suggested fix
`#include` <boost/corosio/select_context.hpp> +#include <boost/corosio/detail/platform.hpp> `#if` BOOST_COROSIO_HAS_SELECTsrc/corosio/src/socket.cpp (1)
10-13: Add an implementation overview block after the includes.Line 10-13: this file contains non-trivial implementation logic but lacks the required post-include /* */ overview comment. Please add a brief design/flow summary.
As per coding guidelines: “Files containing non-trivial implementation logic should include a
/* */block comment after the includes that provides a high-level overview of how the implementation works.”src/corosio/src/detail/iocp/timers_nt.cpp (1)
11-13: Add an implementation overview block after the includes.Line 11-13: this file contains non-trivial logic but lacks the required post-include /* */ overview comment.
As per coding guidelines: “Files containing non-trivial implementation logic should include a
/* */block comment after the includes that provides a high-level overview of how the implementation works.”src/corosio/src/detail/epoll/sockets.cpp (1)
11-14: Add a brief implementation overview after the includes.
This file has substantial logic but lacks the required high-level /* */ overview comment immediately after the includes.As per coding guidelines: Files containing non-trivial implementation logic should include a
/* */block comment after the includes that provides a high-level overview of how the implementation works.Also applies to: 720-720
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #88 +/- ##
===========================================
- Coverage 81.72% 81.30% -0.43%
===========================================
Files 49 53 +4
Lines 4454 4492 +38
===========================================
+ Hits 3640 3652 +12
- Misses 814 840 +26
Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/corosio/src/socket.cpp (1)
10-19: Add an implementation overview block comment after the includes.This file has non-trivial backend selection logic; a brief
/* ... */overview right after the includes is required by guidelines.💡 Example placement
`#include` <boost/corosio/detail/except.hpp> `#include` <boost/corosio/detail/platform.hpp> +/* + * Implementation overview: + * - Selects IOCP-backed socket implementation when BOOST_COROSIO_HAS_IOCP is set. + * - Falls back to POSIX socket_service-based backend otherwise. + */ + `#if` BOOST_COROSIO_HAS_IOCP `#include` "src/detail/iocp/sockets.hpp"As per coding guidelines: Files containing non-trivial implementation logic should include a
/* */block comment after the includes that provides a high-level overview of how the implementation works.
🤖 Fix all issues with AI agents
In `@src/corosio/src/detail/select/acceptors.cpp`:
- Around line 51-59: The success path currently leaves *ec_out untouched which
can leak a previous error; inside the existing ec_out check in acceptors.cpp,
when errn == 0 and cancelled.load(...) is false (i.e., success), explicitly
clear the caller's error by setting *ec_out = {} before the other branches; keep
the existing branches for cancelled (set to capy::error::canceled) and non-zero
errn (set to make_err(errn)), and ensure you only dereference ec_out after the
null check.
- Around line 169-172: The accept() call on the socket (acceptor code using fd_
and storing result in variable accepted) must be retried when it fails with
errno == EINTR; wrap the ::accept(fd_, reinterpret_cast<sockaddr*>(&addr),
&addrlen) invocation in a loop that repeats while accepted == -1 and errno ==
EINTR, and only treat other errno values as real errors (return/handle them).
Ensure you preserve errno for non-EINTR failures and use the same EINTR-handling
pattern already used elsewhere in the codebase.
🧹 Nitpick comments (7)
src/corosio/src/tcp_server.cpp (1)
39-42: Address the TODO: propagatelisten()errors to the caller.The TODO comment indicates that
listen()should return an error_code, but currently any failure fromlisten()is silently ignored andbind()always returns success. This could mask binding failures (e.g., port already in use, permission denied).Would you like me to generate a fix that captures and returns the error from
listen(), or open a new issue to track this improvement?src/corosio/src/detail/iocp/overlapped_op.hpp (1)
33-144: Consider adding a high-level implementation overview.Per the coding guidelines, files with non-trivial implementation logic should include a block comment after the includes explaining how the implementation works. This struct manages Windows IOCP overlapped operations with cancellation support and stop_token integration—a brief overview would help maintainers understand the synchronization model (e.g.,
ready_coordination with GQCS).src/corosio/src/acceptor.cpp (1)
20-22: Consider adding a high-level implementation overview.As per coding guidelines, files with non-trivial implementation logic should include a block comment after the includes explaining how the implementation works. A brief note about the IOCP vs POSIX backend selection model would help maintainers.
📝 Suggested overview
`#include` <boost/corosio/detail/except.hpp> +/* + * acceptor implementation + * + * Uses compile-time backend selection via BOOST_COROSIO_HAS_IOCP: + * - IOCP path: Direct integration with win_sockets service + * - POSIX path: Runtime polymorphism via acceptor_service interface + * (concrete service installed by context constructor) + */ + namespace boost::corosio {src/corosio/src/detail/epoll/sockets.cpp (1)
10-27: Add a brief file-level overview comment after the includes.This file contains non-trivial lifecycle and cancellation logic; a short
/* */overview right after the includes would help maintainers.As per coding guidelines: Files containing non-trivial implementation logic should include a
/* */block comment after the includes that provides a high-level overview of how the implementation works.src/corosio/src/detail/epoll/acceptors.cpp (1)
10-24: Add a brief file-level overview comment after the includes.This new file has substantial control-flow and lifetime handling; a short
/* */overview would help future maintenance.As per coding guidelines: Files containing non-trivial implementation logic should include a
/* */block comment after the includes that provides a high-level overview of how the implementation works.src/corosio/src/detail/select/acceptors.hpp (1)
17-30: Add explicit includes forstd::coroutine_handleandstd::stop_token.
Lines 52 and 54 use these types without explicitly including<coroutine>and<stop_token>. While they are available transitively throughacceptor.hpp, adding explicit includes improves hygiene and avoids fragility.♻️ Proposed fix
`#include` <boost/corosio/detail/config.hpp> `#include` <boost/corosio/acceptor.hpp> `#include` <boost/capy/ex/executor_ref.hpp> `#include` <boost/capy/ex/execution_context.hpp> `#include` "src/detail/intrusive.hpp" `#include` "src/detail/socket_service.hpp" `#include` "src/detail/select/op.hpp" `#include` "src/detail/select/scheduler.hpp" +#include <coroutine> +#include <stop_token> `#include` <memory> `#include` <mutex> `#include` <unordered_map>src/corosio/src/detail/select/acceptors.cpp (1)
14-24: Add a high-level implementation overview block comment.This file contains non-trivial lifecycle and async accept logic but lacks the required /* */ overview after the includes. Please add a short high-level description of the control flow and tricky parts (registration/cancel paths, endpoint caching).
As per coding guidelines: Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.
| sockaddr_in addr{}; | ||
| socklen_t addrlen = sizeof(addr); | ||
| int accepted = ::accept(fd_, reinterpret_cast<sockaddr*>(&addr), &addrlen); | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, find and examine the specific file
fd -t f "acceptors.cpp" src/Repository: cppalliance/corosio
Length of output: 149
🏁 Script executed:
# Read the specific lines mentioned in the review
sed -n '160,180p' src/corosio/src/detail/select/acceptors.cppRepository: cppalliance/corosio
Length of output: 633
🏁 Script executed:
# Look for context around the accept call - get more lines
sed -n '165,185p' src/corosio/src/detail/select/acceptors.cppRepository: cppalliance/corosio
Length of output: 686
🏁 Script executed:
# Search for other accept() calls in the codebase to see if EINTR is handled elsewhere
rg "::accept\(" src/Repository: cppalliance/corosio
Length of output: 304
🏁 Script executed:
# Check for EINTR handling patterns in the same file
rg -i "eintr" src/corosio/src/detail/select/acceptors.cppRepository: cppalliance/corosio
Length of output: 45
🏁 Script executed:
# Look for general error handling patterns in the file
sed -n '1,50p' src/corosio/src/detail/select/acceptors.cppRepository: cppalliance/corosio
Length of output: 1354
🏁 Script executed:
# See the full error handling after accept()
sed -n '165,210p' src/corosio/src/detail/select/acceptors.cppRepository: cppalliance/corosio
Length of output: 1491
🏁 Script executed:
# Check the other accept() call in op.hpp
sed -n '1,20p' src/corosio/src/detail/select/op.hppRepository: cppalliance/corosio
Length of output: 652
🏁 Script executed:
# Find the accept() call in op.hpp and see surrounding code
rg -B 5 -A 10 "::accept\(fd" src/corosio/src/detail/select/op.hppRepository: cppalliance/corosio
Length of output: 651
🏁 Script executed:
# Check if socket is set to non-blocking mode anywhere
rg -i "nonblock\|fcntl" src/corosio/src/detail/select/Repository: cppalliance/corosio
Length of output: 45
🏁 Script executed:
# Look for any signal handling or EINTR patterns in similar async I/O libraries or boost
rg -i "EAGAIN\|EWOULDBLOCK" src/corosio/src/detail/select/acceptors.cppRepository: cppalliance/corosio
Length of output: 45
🏁 Script executed:
# Search for EINTR handling patterns in the entire codebase
rg -i "EINTR" src/Repository: cppalliance/corosio
Length of output: 234
🏁 Script executed:
# Check epoll implementation to see if it handles EINTR differently
rg -B 5 -A 10 "::accept\(" src/corosio/src/detail/epoll/Repository: cppalliance/corosio
Length of output: 45
🏁 Script executed:
# Look for any retry patterns in the codebase
rg -i "do\s*\{|while.*errno|retry" src/corosio/src/detail/select/ | head -20Repository: cppalliance/corosio
Length of output: 45
🏁 Script executed:
# Check epoll acceptors to see if they have different handling
cat src/corosio/src/detail/epoll/acceptors.cpp | grep -A 20 "::accept"Repository: cppalliance/corosio
Length of output: 2121
🏁 Script executed:
# Look at the scheduler EINTR pattern more closely
rg -B 3 -A 3 "saved_errno != EINTR" src/corosio/src/detail/select/scheduler.cppRepository: cppalliance/corosio
Length of output: 305
Retry accept on EINTR.
The accept() call on a blocking socket can be interrupted by signals. Without retrying on EINTR, spurious failures occur. The codebase already distinguishes EINTR from real errors in scheduler contexts; apply the same pattern here.
Proposed fix
- int accepted = ::accept(fd_, reinterpret_cast<sockaddr*>(&addr), &addrlen);
+ int accepted;
+ do {
+ accepted = ::accept(fd_, reinterpret_cast<sockaddr*>(&addr), &addrlen);
+ } while (accepted < 0 && errno == EINTR);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| sockaddr_in addr{}; | |
| socklen_t addrlen = sizeof(addr); | |
| int accepted = ::accept(fd_, reinterpret_cast<sockaddr*>(&addr), &addrlen); | |
| sockaddr_in addr{}; | |
| socklen_t addrlen = sizeof(addr); | |
| int accepted; | |
| do { | |
| accepted = ::accept(fd_, reinterpret_cast<sockaddr*>(&addr), &addrlen); | |
| } while (accepted < 0 && errno == EINTR); | |
🤖 Prompt for AI Agents
In `@src/corosio/src/detail/select/acceptors.cpp` around lines 169 - 172, The
accept() call on the socket (acceptor code using fd_ and storing result in
variable accepted) must be retried when it fails with errno == EINTR; wrap the
::accept(fd_, reinterpret_cast<sockaddr*>(&addr), &addrlen) invocation in a loop
that repeats while accepted == -1 and errno == EINTR, and only treat other errno
values as real errors (return/handle them). Ensure you preserve errno for
non-EINTR failures and use the same EINTR-handling pattern already used
elsewhere in the codebase.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/corosio/src/detail/epoll/acceptors.cpp`:
- Around line 171-186: accept4(fd_) can fail with errno == EINTR when
interrupted by signals; currently the code treats any non-EAGAIN/EWOULDBLOCK
error as permanent. Modify the accept loop around ::accept4 in the acceptor code
so that when errno == EINTR it retries the ::accept4 call (i.e., loop until
accepted >= 0 or errno is not EINTR), preserving the existing handling for
accepted >= 0 (set op.accepted_fd, op.complete, op.impl_ptr, svc_.post) and for
EAGAIN/EWOULDBLOCK. Ensure the retry logic is placed where ::accept4 is invoked
in this function so fd_, op and svc_ behavior remains unchanged.
🧹 Nitpick comments (4)
src/corosio/src/detail/epoll/sockets.cpp (1)
10-27: Add a brief file-level implementation overview.This file has non-trivial cancellation and lifecycle logic; a short /* / overview after the includes would help maintainers. As per coding guidelines: Files containing non-trivial implementation logic should include a / */ block comment after the includes that provides a high-level overview of how the implementation works.
src/corosio/src/detail/epoll/acceptors.cpp (1)
10-24: Add a brief file-level implementation overview.This new acceptor subsystem is non-trivial; a short /* / overview after the includes would aid maintainability. As per coding guidelines: Files containing non-trivial implementation logic should include a / */ block comment after the includes that provides a high-level overview of how the implementation works.
src/corosio/src/detail/select/acceptors.cpp (1)
10-24: Add a brief file-level implementation overview.This file is non-trivial; a short /* / overview after the includes would help future maintenance. As per coding guidelines: Files containing non-trivial implementation logic should include a / */ block comment after the includes that provides a high-level overview of how the implementation works.
src/corosio/src/detail/select/sockets.cpp (1)
10-26: Add a brief file-level implementation overview.This file contains non-trivial reactor/cancellation logic; a short /* / overview after the includes would help maintainability. As per coding guidelines: Files containing non-trivial implementation logic should include a / */ block comment after the includes that provides a high-level overview of how the implementation works.
| sockaddr_in addr{}; | ||
| socklen_t addrlen = sizeof(addr); | ||
| int accepted = ::accept4(fd_, reinterpret_cast<sockaddr*>(&addr), | ||
| &addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC); | ||
|
|
||
| if (accepted >= 0) | ||
| { | ||
| op.accepted_fd = accepted; | ||
| op.complete(0, 0); | ||
| op.impl_ptr = shared_from_this(); | ||
| svc_.post(&op); | ||
| return; | ||
| } | ||
|
|
||
| if (errno == EAGAIN || errno == EWOULDBLOCK) | ||
| { |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's check the full context of the acceptors.cpp file around the mentioned lines
fd src -t cpp -n acceptors | head -20Repository: cppalliance/corosio
Length of output: 293
🏁 Script executed:
# Find the acceptors.cpp file
fd acceptors.cppRepository: cppalliance/corosio
Length of output: 149
🏁 Script executed:
# Get context around lines 171-186
wc -l src/corosio/src/detail/epoll/acceptors.cppRepository: cppalliance/corosio
Length of output: 109
🏁 Script executed:
# View the relevant section and surrounding code
sed -n '160,200p' src/corosio/src/detail/epoll/acceptors.cppRepository: cppalliance/corosio
Length of output: 1544
🏁 Script executed:
# Search for EINTR handling in the codebase
rg "EINTR" -B 2 -A 2Repository: cppalliance/corosio
Length of output: 1163
🏁 Script executed:
# Check if there are similar socket operations that handle EINTR
rg "accept" -B 2 -A 4 --type cppRepository: cppalliance/corosio
Length of output: 50376
🌐 Web query:
POSIX accept4 EINTR specification signal interruption
💡 Result:
- POSIX (accept): The POSIX
accept()specification requires thataccept()fail with-1and seterrno = EINTRif it is interrupted by a caught signal before a valid connection arrives. [1] - accept4 is not POSIX:
accept4()is a non-POSIX extension (e.g., Linux provides it), so POSIX doesn’t standardize its behavior directly; in practice it follows the same interruption rule on systems that implement it. [2] - Linux (accept4 / accept) semantics: On Linux,
accept4()(andaccept()) can returnEINTRwhen a signal is caught before a connection is accepted. [2] - Interaction with SA_RESTART / timeouts (Linux-specific): Linux documents that some “slow” syscalls may be restarted when
SA_RESTARTis used, but socket calls likeaccept()are not restarted (always returnEINTR) if a receive timeoutSO_RCVTIMEOis set. [3]
Practical takeaway: portable code should treat EINTR from accept()/accept4() as a normal interruption and usually retry in a loop, unless you intentionally want signals to break out.
Sources:
[1] POSIX/Open Group accept() specification (EINTR) https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html
[2] Linux accept4(2) man page (EINTR) https://man.archlinux.org/man/core/man-pages/accept4.2.en
[3] Linux signal(7) man page (restart rules; SO_RCVTIMEO exception) https://man.he.net/man7/signal
🏁 Script executed:
sed -n '165,195p' src/corosio/src/detail/epoll/acceptors.cppRepository: cppalliance/corosio
Length of output: 1166
🏁 Script executed:
# Check the complete error handling flow after the accept4 call
sed -n '165,220p' src/corosio/src/detail/epoll/acceptors.cppRepository: cppalliance/corosio
Length of output: 2084
🏁 Script executed:
# Also check the select backend acceptor for comparison
grep -A 20 "accept(" src/corosio/src/detail/select/acceptors.cpp | head -40Repository: cppalliance/corosio
Length of output: 1206
🏁 Script executed:
# Check what happens after the EAGAIN/EWOULDBLOCK block to understand full error flow
sed -n '171,240p' src/corosio/src/detail/epoll/acceptors.cpp | tail -50Repository: cppalliance/corosio
Length of output: 1714
🏁 Script executed:
# Verify if there's any EINTR handling elsewhere in the method
grep -n "EINTR" src/corosio/src/detail/epoll/acceptors.cppRepository: cppalliance/corosio
Length of output: 45
🏁 Script executed:
# Confirm EINTR is not handled by looking at the complete error handling
sed -n '211,225p' src/corosio/src/detail/epoll/acceptors.cppRepository: cppalliance/corosio
Length of output: 384
Handle EINTR by retrying accept4 when interrupted by signals.
POSIX specifies that accept() (and by extension accept4()) can return -1 with errno == EINTR when a signal interrupts the call before a connection arrives. Without retry logic, spurious signal interruptions will propagate as errors rather than transparently handling the interruption.
🛠️ Proposed fix
- int accepted = ::accept4(fd_, reinterpret_cast<sockaddr*>(&addr),
- &addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC);
+ int accepted;
+ do {
+ accepted = ::accept4(fd_, reinterpret_cast<sockaddr*>(&addr),
+ &addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC);
+ } while (accepted < 0 && errno == EINTR);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| sockaddr_in addr{}; | |
| socklen_t addrlen = sizeof(addr); | |
| int accepted = ::accept4(fd_, reinterpret_cast<sockaddr*>(&addr), | |
| &addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC); | |
| if (accepted >= 0) | |
| { | |
| op.accepted_fd = accepted; | |
| op.complete(0, 0); | |
| op.impl_ptr = shared_from_this(); | |
| svc_.post(&op); | |
| return; | |
| } | |
| if (errno == EAGAIN || errno == EWOULDBLOCK) | |
| { | |
| sockaddr_in addr{}; | |
| socklen_t addrlen = sizeof(addr); | |
| int accepted; | |
| do { | |
| accepted = ::accept4(fd_, reinterpret_cast<sockaddr*>(&addr), | |
| &addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC); | |
| } while (accepted < 0 && errno == EINTR); | |
| if (accepted >= 0) | |
| { | |
| op.accepted_fd = accepted; | |
| op.complete(0, 0); | |
| op.impl_ptr = shared_from_this(); | |
| svc_.post(&op); | |
| return; | |
| } | |
| if (errno == EAGAIN || errno == EWOULDBLOCK) | |
| { |
🤖 Prompt for AI Agents
In `@src/corosio/src/detail/epoll/acceptors.cpp` around lines 171 - 186,
accept4(fd_) can fail with errno == EINTR when interrupted by signals; currently
the code treats any non-EAGAIN/EWOULDBLOCK error as permanent. Modify the accept
loop around ::accept4 in the acceptor code so that when errno == EINTR it
retries the ::accept4 call (i.e., loop until accepted >= 0 or errno is not
EINTR), preserving the existing handling for accepted >= 0 (set op.accepted_fd,
op.complete, op.impl_ptr, svc_.post) and for EAGAIN/EWOULDBLOCK. Ensure the
retry logic is placed where ::accept4 is invoked in this function so fd_, op and
svc_ behavior remains unchanged.
Summary by CodeRabbit
Refactor
New Features
Bug Fixes
✏️ Tip: You can customize this high-level summary in your review settings.