server: fix data races found by the nightly ThreadSanitizer job#9
Merged
Conversation
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #9
Scan targets checked: wolfcert-bugs, wolfcert-src
No new issues found in the changed files. ✅
There was a problem hiding this comment.
Pull request overview
Fixes ThreadSanitizer-reported data races in the server shutdown path and in an integration test’s cross-thread port publication, improving correctness of threaded operation under TSan and real concurrency.
Changes:
- Replace
WolfCertServer.stoppingwithwolfSSL_Atomic_Intand useWOLFSSL_ATOMIC_LOAD/STOREfor cross-thread stop signaling. - Make the accept loop
poll()with a short timeout instead of blocking inaccept(), and stop closinglisten_fdfromwolfcert_server_stop(). - Fix the
test_tls_httpport handoff race by publishing/polling the port viawolfSSL_Atomic_Int.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
tests/integration/test_tls_http.c |
Uses wolfSSL_Atomic_Int for the server port handoff between threads to satisfy TSan. |
src/server.c |
Reworks the accept loop to poll and uses atomic stop signaling; removes cross-thread listen_fd shutdown/close. |
src/internal.h |
Updates WolfCertServer to store the stop flag as wolfSSL_Atomic_Int. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
philljj
requested changes
Jul 16, 2026
philljj
left a comment
Contributor
There was a problem hiding this comment.
Looks good, just one nit on poll(2) event handling.
The nightly Sanitizers workflow's ThreadSanitizer subjob failed on every threaded roundtrip once the TSan build started running (the prior -Werror fix let it get far enough to execute). Two distinct data races: - wolfcert_server_run()/wolfcert_server_stop(): `stopping` was a plain volatile int, written by the stopping thread (or the wolfcert-server CLI signal handler) and polled by the accept loop. volatile carries no happens-before, so TSan flags it; stop() also closed listen_fd while the accept loop still read it. Make `stopping` a wolfSSL_Atomic_Int (wc_port.h) and have the accept loop poll() the listener on a short timeout so it re-checks the flag itself. stop() now only sets the flag and never touches listen_fd (free() closes it after the serving thread is joined). This also drops the reliance on shutdown()/close() waking a blocked accept(), which is not portable to BSD/macOS. - test_tls_http: srv_thread published the ephemeral port into a main-thread stack struct that main spin-polled without synchronization. Make that field a wolfSSL_Atomic_Int as well. The wc_port atomics degrade to volatile int under WOLFSSL_NO_ATOMICS, so the client/embedded path is unchanged. The accept loop also retries transient per-connection errors (ECONNABORTED/ECONNRESET) instead of tearing the listener down over a single misbehaving peer. Verified: the 12 roundtrip|tls_http tests pass clean under -fsanitize=thread (halt_on_error=1); the full 24-test suite stays green.
Frauschi
force-pushed
the
tsan_server_races
branch
from
July 16, 2026 16:22
671f516 to
c750799
Compare
philljj
approved these changes
Jul 16, 2026
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.
What & why
The nightly
Sanitizersworkflow's ThreadSanitizer job has been failing on every threaded roundtrip since the TSan build actually started running (the earlier-Werrorfix let it get far enough to execute the tests). Root cause: two genuine data races.1.
stoppingflag —src/server.cWolfCertServer.stoppingwas a plainvolatile int, written bywolfcert_server_stop()(from another thread in the test harness, or from thewolfcert-serverCLI'sSIGINT/SIGTERMhandler) and polled by the accept loop inwolfcert_server_run().volatileestablishes no happens-before, so TSan flags it. Separately,stop()close()dlisten_fdwhile the accept loop still read it — a second race hidden behind the first.2.
porthandoff —tests/integration/test_tls_http.csrv_threadpublished the ephemeral listener port into a main-thread stack struct thatmainspin-polled without synchronization.The fix
stopping→wolfSSL_Atomic_Int(wc_port.h), accessed viaWOLFSSL_ATOMIC_LOAD/WOLFSSL_ATOMIC_STORE. Gives the cross-thread handoff a happens-before edge and an async-signal-safe store for the CLI.poll()s the listener on a short timeout and re-checks the flag itself.stop()only sets the flag and never toucheslisten_fd(closed byfree()after the serving thread is joined). This removes the second race and drops the reliance onshutdown()/close()waking a blockedaccept(), which is not portable to BSD/macOS.test_tls_http'sportfield →wolfSSL_Atomic_Intas well.ECONNABORTED/ECONNRESET) instead of tearing the listener down over a single misbehaving peer.Embedded / portability
wc_port.h's atomics degrade tovolatile intunderWOLFSSL_NO_ATOMICS, so the client/embedded path is unchanged — on a no-atomics target the field is literallyvolatile intagain, as before. The change is confined to the server subsystem (WOLFCERT_ENABLE_SERVER) and one integration test.Verification
roundtrip|tls_httppass clean under-fsanitize=thread(halt_on_error=1); full 24-test suite green.Sanitizersworkflow dispatched on this branch — ThreadSanitizer, ASan+UBSan, and valgrind all ✅ (run 29482351976).