feat(native): complete async-op shadowing across all I/O types#253
Conversation
|
An automated preview of the documentation is available at https://253.corosio.prtest3.cppalliance.org/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-05-26 18:23:38 UTC |
|
GCOVR code coverage report https://253.corosio.prtest3.cppalliance.org/gcovr/index.html Build time: 2026-05-26 18:28:18 UTC |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #253 +/- ##
========================================
Coverage 77.76% 77.76%
========================================
Files 96 96
Lines 7264 7264
Branches 1775 1775
========================================
Hits 5649 5649
Misses 1104 1104
Partials 511 511
Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
Extend the shadow pattern (concrete-class method names hidden by
derived native_*<Backend> templates that return strongly-typed
awaitables instead of dispatching virtually) so every async
operation on every public I/O type has a native_* counterpart.
Before this branch, only a subset of the async surface was
shadowed. native_tcp_socket and native_tcp_acceptor shadowed
their read/write/accept/connect ops, but native_udp_socket
covered only send_to/recv_from, and the local-socket and file
types had no shadow at all. Code holding a native_X<Backend>
reference therefore went through the virtual io_object dispatch
for any non-shadowed call, defeating the point of using the
typed wrapper.
This commit closes the gap:
- native_udp_socket gains connect, send, recv shadows.
- New native_local_stream_socket shadows read_some, write_some,
connect.
- New native_local_stream_acceptor shadows accept(peer&) and
the move-accept overload (returning a
native_local_stream_socket<Backend>).
- New native_local_datagram_socket shadows send_to, recv_from,
connect, send, recv.
- New native_stream_file shadows read_some, write_some.
- New native_random_access_file shadows read_some_at,
write_some_at.
- Every shadow type also gets wait() returning a typed
native_wait_awaitable.
Tests under test/unit/native/ exercise each new shadow with a
static_assert that pins the shadowing contract (the native op
must return a type distinct from the concrete base op), plus
runtime checks of the awaitable path and a polymorphic-slice
test that verifies the base class still works via virtual
dispatch when the object is used through its non-native
interface.
Supporting bits:
- backend.hpp gains the file-type tag typedefs (stream_file_type,
random_access_file_type, and *_service_type) for every
backend so create_handle<service_type>(ctx) compiles in the
new native_*_file wrappers.
- stream_file and random_access_file grow protected constructors
so the native virtual-base initialization works (io_stream
virtually inherits io_object; only the most-derived class
initializes it).
- local_stream_acceptor::bind now honors bind_option::unlink_existing
on Windows via DeleteFileA — the option was previously a no-op
in the non-POSIX branch, which broke testUnlinkExisting on the
iocp variant.
- win_tcp_service::connect_ex / accept_ex getters move into the
class body so TUs that include only the service header (the
new native_local_stream_socket test among them) get the
inline definitions.
- win_local_stream_service.hpp pulls in the acceptor header
directly so its inline shutdown() sees the full
win_local_stream_acceptor_internal type regardless of
consumer include order.
- A portable test/unit/local_temp.hpp helper replaces the old
POSIX-only mkdtemp/unlink pattern in the local-socket tests,
using std::filesystem + a random_device-seeded RNG so
parallel ctest processes don't collide on /tmp paths.
Known platform gaps documented in-file:
- local_datagram_socket tests stay POSIX-only at the
top-of-file. Windows has never shipped AF_UNIX SOCK_DGRAM;
the very first WSASocket(AF_UNIX, SOCK_DGRAM, ...) returns
WSAESOCKTNOSUPPORT.
- local_stream_socket's three socketpair-based tests
(testReadWrite, testSocketPair, testAvailable) and the
raw-fd testRelease remain per-test POSIX-gated;
make_local_stream_pair is gated POSIX-only in the public
header because socketpair() doesn't exist on Windows. TCP
socket tests already exercise the equivalent read/write
paths on Windows IOCP.
…unt tests Replace the 10ms delay timer that sequenced waiter registration before the reset with explicit poll() drains. The previous structure relied on the IOCP scheduler dispatching the two t.wait() suspensions before the delay timer expired; on Windows release builds the order isn't guaranteed and the test would intermittently observe zero canceled waiters.
Extend the shadow pattern (concrete-class method names hidden by derived native_ templates that return strongly-typed awaitables instead of dispatching virtually) so every async operation on every public I/O type has a native_ counterpart.
Before this branch, only a subset of the async surface was shadowed. native_tcp_socket and native_tcp_acceptor shadowed their read/write/accept/connect ops, but native_udp_socket covered only send_to/recv_from, and the local-socket and file types had no shadow at all. Code holding a native_X reference therefore went through the virtual io_object dispatch for any non-shadowed call, defeating the point of using the typed wrapper.
This commit closes the gap:
Tests under test/unit/native/ exercise each new shadow with a static_assert that pins the shadowing contract (the native op must return a type distinct from the concrete base op), plus runtime checks of the awaitable path and a polymorphic-slice test that verifies the base class still works via virtual dispatch when the object is used through its non-native interface.
Supporting bits:
Known platform gaps documented in-file: