Multicast receive + complete the realtime story + cleanups#22
Open
tap wants to merge 4 commits into
Open
Conversation
- win32/UdpSocket.h: GetCurrentTimeMs() now uses std::chrono::steady_clock (matching the posix backend) instead of timeGetTime(), which wrapped after ~49 days. Resolves the FIXME. Verified: win32 smoke compiles clean (MinGW -Wshadow -Werror) and OscUdpTest passes under Wine. - ROADMAP.md: the INCLUDED_OSCPACK_* guard rename and the strcpy/gethostbyname / uncompiled-ip-backend deferrals are done -- updated those stale "Deferred" notes; refreshed the top status line. - STATUS.md: Phase 1/2 issues exist (#3-#8, #14-#19); only the "Phase 2 - Reach" milestone object remains an owner action. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MMR6tmM7H3obaL7SX14bkJ
…cy benchmark The RTSan deferral was a non-throwing realtime blob accessor and a worst-case latency benchmark. Both done, plus the analogous bool accessor. - AsBlobUnchecked() and AsBoolUnchecked() are now throw-free and marked OSCTAP_REALTIME. Like the other *Unchecked accessors they trust the validation done at construction (ReceivedMessage::TryInit bounds-checks every blob), so the redundant re-validation/throw is dropped. Every *Unchecked read accessor is now on the realtime contract -- no exceptions. - OscRealtimeTest reads the blob payload and bool through these accessors inside the [[clang::nonblocking]] hot path. Verified under Clang-20: -Wfunction-effects -Werror (static) and -fsanitize=realtime (runtime) both pass. - tests/OscLatencyBench.cpp: worst-case parse/serialize latency (min/median/p99/max ns), the secondary signal the sanitizer strategy calls for. Built as a target; the rtsan CI job runs it (informational, non-gating). - ROADMAP/STATUS/test comments updated; fuzzer still ASan/UBSan-clean (200k mutations) after the blob-accessor change; full suite 8/8. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MMR6tmM7H3obaL7SX14bkJ
…n32) Closes the last open Phase 2 feature box (issue #19). - UdpSocket<Impl_T>::JoinMulticastGroup() / LeaveMulticastGroup() forward to the impl; posix and win32 UdpSocketImplementation implement them via setsockopt IP_ADD_MEMBERSHIP / IP_DROP_MEMBERSHIP (default interface). Available on any UDP receive socket once bound; closing the socket leaves joined groups automatically. - tests/OscMulticastTest.cpp: real loopback -- bind, join 239.7.7.7, send 3 OSC messages to the group, assert receipt. Skip-resilient (like the unicast socket tests). Wired into CMake (POSIX) and the win32-wine CI job. - Docs: API.md, ROADMAP.md (multicast now done), STATUS.md. Verified: OscMulticastTest passes on POSIX (ASan/UBSan-clean) and on win32 under Wine; full hosted suite 9/9; aarch64 cross-build clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MMR6tmM7H3obaL7SX14bkJ
OscMulticastTest died with SIGPIPE on the macOS runners: a connected-UDP send() to an unrouted multicast group raises SIGPIPE on macOS/BSD (the CI hosts have no multicast route), killing the process before the test could SKIP. - posix UdpSocketImplementation now sets SO_NOSIGPIPE (where defined: macOS/BSD) so send() returns an error instead of raising SIGPIPE -- mirroring the TCP backend. The library should never SIGPIPE the host process. - OscMulticastTest also installs SIG_IGN for SIGPIPE (non-Windows) as a belt-and-suspenders guard, so an unsupported-multicast environment SKIPs cleanly. Linux + Wine multicast still deliver and pass; full suite 9/9. SO_NOSIGPIPE is macOS/BSD-only (the #ifdef is skipped on Linux). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MMR6tmM7H3obaL7SX14bkJ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three focused commits picking up loose ends after the last merge. Each independently green; please Rebase and merge (keep the commits).
Multicast receive (issue #19 — the last open Phase 2 feature)
UdpSocket::JoinMulticastGroup()/LeaveMulticastGroup()(IP_ADD/DROP_MEMBERSHIP) on both posix and win32, available on any UDP receive socket once bound.tests/OscMulticastTest.cpp— real loopback (join239.7.7.7, send 3 OSC messages to the group, assert receipt), skip-resilient like the other socket tests. Wired into the win32-wine CI job too.Complete the realtime story (the RTSan deferral)
AsBlobUnchecked()andAsBoolUnchecked()are now throw-free andOSCTAP_REALTIME— they trust the validation done at construction, like the other*Uncheckedaccessors. Every*Uncheckedread accessor is now on the realtime contract.OscRealtimeTestreads the blob payload + bool on the[[clang::nonblocking]]hot path; verified under Clang-20 with-Wfunction-effects -Werror(static) and-fsanitize=realtime(runtime).tests/OscLatencyBench.cpp— worst-case parse/serialize latency (min/median/p99/max ns), the secondary signal the strategy calls for; run informationally in thertsanCI job.Cleanups
win32/UdpSocket.h:GetCurrentTimeMs()now usesstd::chrono::steady_clock(matches posix; no ~49-daytimeGetTime()wrap) — resolves theFIXME.strcpy/gethostbyname, uncompiled backends — all done).Full hosted suite 9/9.
Closes #19.
🤖 Generated with Claude Code
https://claude.ai/code/session_01MMR6tmM7H3obaL7SX14bkJ
Generated by Claude Code