Skip to content

feat: S11.09 AtomicCounter family + TLS + FatFs onto PoolAllocator#415

Merged
DavidCozens merged 9 commits into
mainfrom
refactor/s11-09-atomics-tls-fatfs-sweep
May 20, 2026
Merged

feat: S11.09 AtomicCounter family + TLS + FatFs onto PoolAllocator#415
DavidCozens merged 9 commits into
mainfrom
refactor/s11-09-atomics-tls-fatfs-sweep

Conversation

@DavidCozens

@DavidCozens DavidCozens commented May 20, 2026

Copy link
Copy Markdown
Owner

Purpose

Closes #412. Closes out E11's class-by-class migration with the four storage-cast classes that don't fit one platform umbrella — StdAtomicCounter, WindowsAtomicCounter, FatFsFile, TlsStream. Each gets the canonical 3-TU split (Class.c + ClassPrivate.h + ClassStatic.c) + SolidSyslogPoolAllocator, with the public <Class>Storage typedef and SOLIDSYSLOG_*_SIZE enum deleted from each public header.

After this lands, only S11.10 (SolidSyslog core retrofit) and S11.11 (wholesale MISRA D.002 storage-cast deviation cleanup) remain in E11. Per pre-flight agreement those stay as separate stories.

Change Description

Five commits on the branch (squash-merge collapses to one on main):

  • feat: S11.09 add SolidSyslogNullAtomicCounter — new public GoF null with Increment returning 1U unconditionally. RFC 5424 §7.3.1 forbids sequenceId 0; 1U is indistinguishable from post-power-on / post-wrap state, which is the safest fallback. Symmetric with the S11.06 wave (NullDatagram / NullStream / NullFile / NullResolver). _Get is silent — the bad-setup error fires from *Static.c::Create at pool exhaustion, matching the existing contract.

  • refactor: S11.09 migrate AtomicCounter family onto PoolAllocator — Std + Windows backends in one commit (not two as the story body sequenced them). The two backends share the TestAtomicCounter_* shim signature in Tests/SolidSyslogAtomicCounterTestHelper.h; splitting per backend would leave the inactive platform's compile broken between commits. Combined commit preserves the per-commit must-compile invariant. Adds TestAtomicCounter_PoolSize() so the backend-agnostic contract test can runtime-gate the two-counter independence scenario.

  • refactor: S11.09 migrate FatFsFile onto PoolAllocator — deletes the SOLIDSYSLOG_FATFS_FILE_SIZE = sizeof(intptr_t) * 180U enum from the public header (the 180-intptr footprint driven by FF_MAX_SS=512 and FIL's sector buffer is now an internal pool concern). The planned S21.03 follow-up that was going to make FF_MAX_SS > 512 overridable becomes simpler — it's now a pool-internal CMake tunable, not a public-API concern.

  • refactor: S11.09 migrate TlsStream onto PoolAllocator — largest of the four (~460 lines pre-migration). Refactor-only: bounded handshake retry via the injected Sleep callback, mTLS all-or-nothing client-identity contract, BIO_METHOD lifecycle, SSL_read fail-fast on non-WANT_READ, idempotent Close all preserved verbatim. Drops one obsolete test (CreateReturnsHandleInsideCallerSuppliedStorage — asserted the storage-cast invariant which no longer holds).

  • docs: update DEVLOG for S11.09 — per-commit narrative, decisions, per-class delta numbers, handoff notes.

Public API changes

/* Before */
struct SolidSyslogAtomicCounter* SolidSyslogStdAtomicCounter_Create(SolidSyslogStdAtomicCounterStorage*);
struct SolidSyslogAtomicCounter* SolidSyslogWindowsAtomicCounter_Create(SolidSyslogWindowsAtomicCounterStorage*);
struct SolidSyslogFile*          SolidSyslogFatFsFile_Create(SolidSyslogFatFsFileStorage*);
struct SolidSyslogStream*        SolidSyslogTlsStream_Create(SolidSyslogTlsStreamStorage*, const struct SolidSyslogTlsStreamConfig*);

/* After */
struct SolidSyslogAtomicCounter* SolidSyslogStdAtomicCounter_Create(void);
struct SolidSyslogAtomicCounter* SolidSyslogWindowsAtomicCounter_Create(void);
struct SolidSyslogFile*          SolidSyslogFatFsFile_Create(void);
struct SolidSyslogStream*        SolidSyslogTlsStream_Create(const struct SolidSyslogTlsStreamConfig*);

/* New */
struct SolidSyslogAtomicCounter* SolidSyslogNullAtomicCounter_Get(void);

SolidSyslog{Std,Windows}AtomicCounterStorage, SolidSyslogFatFsFileStorage, SolidSyslogTlsStreamStorage typedefs and their SOLIDSYSLOG_*_SIZE enums deleted from public headers. New tunables: SOLIDSYSLOG_{STD,WINDOWS}_ATOMIC_COUNTER_POOL_SIZE, SOLIDSYSLOG_FATFS_FILE_POOL_SIZE, SOLIDSYSLOG_TLS_STREAM_POOL_SIZE (all default 1U).

Decisions worth flagging

  • One new public GoF null onlySolidSyslogNullAtomicCounter. NullStream (S11.06) covers TlsStream; NullFile (S11.06) covers FatFsFile.
  • Pool sizes all 1U. TlsStream could go 2U on the same logic as the TCP streams, but composition belongs at the underlying-stream layer, not the TLS layer.
  • AtomicCounter contract-test two-counter scenario runtime-gated. New TestAtomicCounter_PoolSize() helper lets the backend-agnostic test detect when the pool isn't big enough and TEST_EXIT cleanly. The tunable-override-debug preset bumps both AtomicCounter pool sizes to 2 so the gated test actually runs in CI.
  • AtomicCounter whitebox-test access preserved. Each backend's _Init(uint32_t) helper (used by the wraparound-at-INT32_MAX contract test) stays in *.c alongside _Increment. The TestHelper still #includes the .c whitebox and now also sees the struct via *Private.h.
  • TlsStream DEFAULT_INSTANCE / DESTROYED_INSTANCE static consts go away. Initialise sets vtable fields + zeroes Ctx/Ssl/BioMethod explicitly; Cleanup overwrites the abstract base with *SolidSyslogNullStream_Get(). Matches every other 3-TU-migrated class.

Test Evidence

Per-class Pool TEST_GROUPs (9 tests each) mirror SolidSyslogWindowsMutexPool's canonical shape:

  • SolidSyslogStdAtomicCounterPool — 9 tests, gcc/clang
  • SolidSyslogWindowsAtomicCounterPool — 9 tests, MSVC only
  • SolidSyslogFatFsFilePool — 9 tests, freertos-host (only place FatFs sources compile)
  • SolidSyslogTlsStreamPool — 9 tests, gcc/clang with OpenSSL

SolidSyslogNullAtomicCounter — 2 tests (returns 1, idempotent).

Existing tests migrated mechanically (drop *Storage locals, switch to handle-based teardown). One obsolete test removed (TlsStream::CreateReturnsHandleInsideCallerSuppliedStorage).

Local validation

  • Debug: 1278 tests green (gcc container) + 37 FatFs tests (freertos-host container)
  • Sanitize: full suite green; pre-existing UBSan finding on Tests/FileFake.c:424 from S10.04 unrelated to this PR
  • Coverage: 99.5% line aggregated, 100% line on every new/migrated file when measured per-binary:
    • SolidSyslogStdAtomicCounter.c 20/20, SolidSyslogStdAtomicCounterStatic.c 26/26
    • SolidSyslogNullAtomicCounter.c 4/4
    • SolidSyslogFatFsFile.c + SolidSyslogFatFsFileStatic.c 83/83 (via the separate SolidSyslogFatFsFileTest binary)
    • SolidSyslogTlsStream.c 183/183, SolidSyslogTlsStreamStatic.c 26/26
  • Tidy: clean on every new/migrated file (gcc CI image)
  • cppcheck: clean
  • clang-format: clean
  • IWYU: clean via cpputest-clang container (caught one stray include in SolidSyslogNullAtomicCounter.c after the first consumer landed — folded into the AtomicCounter migration commit)
  • OpenSSL integration: 9/9 green

Per-class re-run at SOLIDSYSLOG_<CLASS>_POOL_SIZE=3 via SOLIDSYSLOG_USER_TUNABLES_FILE: green (the tunable-override-debug preset already exercises this via the bumped AtomicCounter tunables).

CI-only gates remaining

Per pre-flight agreement MSVC validation moves to CI for this story (departing from feedback_local_msvc for S11.09 specifically — the existing build-windows-msvc + integration-windows-openssl jobs cover the surface):

  • build-windows-msvcWindowsAtomicCounter + TlsStream/Winsock BDD target
  • bdd-windows-otel — exercises TlsStream_Create(&config) against the cert-validated syslog-ng oracle
  • bdd-freertos-qemu — exercises FatFsFile pool migration via set store file BDD scenario
  • analyze-iwyu — already validated locally, CI re-runs

Areas Affected

  • Platform/Atomics/StdAtomicCounter 3-TU split + new Private header
  • Platform/Windows/WindowsAtomicCounter 3-TU split + new Private header (no change to other Windows classes)
  • Platform/FatFs/FatFsFile 3-TU split + new Private header; INTERFACE library shape preserved
  • Platform/OpenSsl/TlsStream 3-TU split + new Private header
  • Core/Interface/SolidSyslogTunablesDefaults.h — four new pool-size tunables
  • Core/Source/SolidSyslogErrorMessages.h — four new pool-exhaustion / unknown-destroy message constants
  • Core/Interface/SolidSyslogNullAtomicCounter.h + Core/Source/SolidSyslogNullAtomicCounter.c — new public GoF null
  • Tests/ — new *PoolTest.cpp files; contract test runtime-gated on pool size; existing tests mechanically migrated; TestAtomicCounter_PoolSize() helper added
  • Tests/Fixtures/SmallMessageSizeTunables.h — bumps both AtomicCounter pool sizes to 2U
  • Bdd/Targets/counterStorage / storeFileStorage / tlsStreamStorage locals dropped from Linux, Windows, FreeRtos main + the two TLS senders + the OpenSSL integration test
  • CLAUDE.md — audience-table rows updated for StdAtomicCounter, WindowsAtomicCounter, FatFsFile, TlsStream; new NullAtomicCounter row added
  • DEVLOG.md — S11.09 entry

Summary by CodeRabbit

  • New Features

    • TLS stream support for encrypted syslog transport with configurable options
    • Null atomic-counter fallback providing a safe constant sequence value
  • Improvements

    • Simplified creation APIs — atomic counters, file handles, and TLS streams no longer require caller-provided storage
    • Runtime pool backing for counters, files, and TLS streams with automatic allocation/fallback
    • Safer cleanup to avoid use-after-destroy
  • Tests

    • New and expanded tests validating pool behavior and fallback handling

Review Change Stack

DavidCozens and others added 5 commits May 20, 2026 14:18
Pool-exhaustion fallback for both AtomicCounter backends
(StdAtomicCounter and WindowsAtomicCounter). Wired under the
existing HAVE_ATOMIC_COUNTER gate alongside the public vtable
dispatcher.

Increment returns 1U unconditionally — RFC 5424 §7.3.1 requires
sequenceIds in [1, 2^31 - 1] and never 0, so 1U is indistinguishable
from the post-power-on / post-wrap state and is the safest fallback
when an integrator's pool is exhausted. The Null itself is silent;
the error is emitted from *Static.c::Create at the bad-setup point
per the existing pool-exhaustion contract.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Splits StdAtomicCounter and WindowsAtomicCounter onto the canonical
3-TU pattern (Class.c + ClassPrivate.h + ClassStatic.c) using
SolidSyslogPoolAllocator, and deletes the public storage typedefs +
SOLIDSYSLOG_*_SIZE enums. Pool-exhaustion and use-after-destroy
both fall back to the shared SolidSyslogNullAtomicCounter from the
prior commit; SolidSyslog_Error fires once at Create-time per the
existing bad-setup contract.

Combined into one commit because both backends share the
TestAtomicCounter_* shim in Tests/SolidSyslogAtomicCounterTestHelper.h
— splitting per backend would leave the inactive platform's build
broken between commits.

Adds:
- SOLIDSYSLOG_{STD,WINDOWS}_ATOMIC_COUNTER_POOL_SIZE (default 1U)
- SOLIDSYSLOG_ERROR_MSG_{STD,WINDOWS}ATOMICCOUNTER_{POOL_EXHAUSTED,UNKNOWN_DESTROY}
- TestAtomicCounter_PoolSize() in the shared helper interface so the
  backend-agnostic contract test can runtime-gate the two-counter
  independence scenario
- Per-backend Pool TEST_GROUP (9 tests each, mirrors WindowsMutexPool)
- Tunable bumps in SmallMessageSizeTunables.h so
  tunable-override-debug exercises the two-counter contract test

Caller updates: drops counterStorage locals in Bdd/Targets/Linux,
Bdd/Targets/Windows, Bdd/Targets/FreeRtos, Tests/SolidSyslogTest.cpp
and Tests/SolidSyslogMetaSdTest.cpp.

Trims an unused include in SolidSyslogNullAtomicCounter.c spotted
by IWYU once the first consumer landed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Splits FatFsFile onto the canonical 3-TU pattern (Class.c +
ClassPrivate.h + ClassStatic.c) using SolidSyslogPoolAllocator, and
deletes the public SolidSyslogFatFsFileStorage typedef + the
SOLIDSYSLOG_FATFS_FILE_SIZE enum from the public header. Sizing now
lives entirely behind the INTERFACE library — integrators no longer
need to allocate or reason about the 180-intptr FIL+sector-buffer
blob. The planned S21.03 follow-up that was going to make FF_MAX_SS
> 512 overridable becomes simpler: it becomes a pool-internal
concern, not a public-API one.

Pool-exhaustion falls back to the shared SolidSyslogNullFile;
use-after-destroy is a safe no-op via Cleanup overwriting the base
vtable. SolidSyslog_Error fires once at Create-time per the existing
bad-setup contract.

Adds:
- SOLIDSYSLOG_FATFS_FILE_POOL_SIZE (default 1U)
- SOLIDSYSLOG_ERROR_MSG_FATFSFILE_{POOL_EXHAUSTED,UNKNOWN_DESTROY}
- 9-test Pool TEST_GROUP mirroring WindowsMutexPool
- ErrorHandlerFake + ConfigLockFake link deps for the FatFs test exe

INTERFACE library shape preserved — Platform/FatFs/CMakeLists.txt
still declares headers only; SolidSyslogFatFsFileStatic.c joins
SolidSyslogFatFsFile.c in every consumer's source list (FreeRtos
BDD target + Tests/FatFs).

Caller updates: drops storeFileStorage local in
Bdd/Targets/FreeRtos/main.c and the test storage in
SolidSyslogFatFsFileTest's TEST_GROUP fixture.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Splits TlsStream onto the canonical 3-TU pattern (Class.c +
ClassPrivate.h + ClassStatic.c) using SolidSyslogPoolAllocator, and
deletes the public SolidSyslogTlsStreamStorage typedef + the
SOLIDSYSLOG_TLS_STREAM_SIZE enum from the public header. Create
keeps its config argument; the storage arg goes away.

Pool-exhaustion falls back to the shared SolidSyslogNullStream;
use-after-destroy is a safe no-op via Cleanup overwriting the base
vtable. SolidSyslog_Error fires once at Create-time per the existing
bad-setup contract.

TlsStream-specific semantics preserved verbatim: bounded handshake
retry via the injected Sleep callback, mTLS all-or-nothing client-
identity contract, BIO_METHOD lifecycle (created on Open, freed on
Close + Destroy), SSL_read fail-fast on non-WANT_READ errors,
idempotent Close.

Adds:
- SOLIDSYSLOG_TLS_STREAM_POOL_SIZE (default 1U)
- SOLIDSYSLOG_ERROR_MSG_TLSSTREAM_{POOL_EXHAUSTED,UNKNOWN_DESTROY}
- 9-test Pool TEST_GROUP mirroring WindowsMutexPool

Removes:
- The CreateReturnsHandleInsideCallerSuppliedStorage test (asserted
  the obsolete storage-cast invariant)

Caller updates: drops tlsStreamStorage locals in
Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_{Posix,Winsock}Tcp.c
and Tests/OpenSslIntegration/SolidSyslogTlsStreamIntegrationTest.cpp.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bae5c42d-f0a5-484d-9b66-5c5f8254567d

📥 Commits

Reviewing files that changed from the base of the PR and between 0be6170 and cd077c0.

📒 Files selected for processing (5)
  • DEVLOG.md
  • Platform/OpenSsl/Source/SolidSyslogTlsStream.c
  • Tests/SolidSyslogTest.cpp
  • Tests/SolidSyslogTlsStreamPoolTest.cpp
  • Tests/SolidSyslogTlsStreamTest.cpp
✅ Files skipped from review due to trivial changes (1)
  • DEVLOG.md

📝 Walkthrough

Walkthrough

This PR migrates StdAtomicCounter, WindowsAtomicCounter, TlsStream, and FatFsFile to pool-backed Create/Destroy APIs, adds a NullAtomicCounter fallback, introduces pool-size tunables and error messages, updates CMake/build wiring, and updates tests and all callers to the new allocation model.

Changes

Pool Allocator Migration for Four Components

Layer / File(s) Summary
Public API Contracts and Compile-Time Tunables
Core/Interface/SolidSyslogNullAtomicCounter.h, Core/Interface/SolidSyslogTunablesDefaults.h, Platform/Atomics/Interface/SolidSyslogStdAtomicCounter.h, Platform/Windows/Interface/SolidSyslogWindowsAtomicCounter.h, Platform/FatFs/Interface/SolidSyslogFatFsFile.h, Platform/OpenSsl/Interface/SolidSyslogTlsStream.h, CLAUDE.md
Added SolidSyslogNullAtomicCounter_Get; removed caller-owned storage typedefs and size enums; changed Create signatures to parameterless forms (TlsStream keeps config-only); added pool-size tunables with >=1 checks and updated public docs.
Core Infrastructure: Error Messages and Build Wiring
Core/Source/SolidSyslogErrorMessages.h, Core/Source/CMakeLists.txt, Platform/Atomics/CMakeLists.txt, Platform/OpenSsl/CMakeLists.txt, Platform/Windows/CMakeLists.txt, DEVLOG.md
Added pool-exhausted and unknown-destroy error messages for each component; conditional CMake wiring for static pool sources; DEVLOG documents migration and validation.
Null Atomic Counter Fallback
Core/Source/SolidSyslogNullAtomicCounter.c
Implements singleton null counter whose Increment returns 1U and provides SolidSyslogNullAtomicCounter_Get() for fallback on pool exhaustion.
StdAtomicCounter Pool Migration: Private, Impl, and Pool
Platform/Atomics/Source/SolidSyslogStdAtomicCounterPrivate.h, Platform/Atomics/Source/SolidSyslogStdAtomicCounter.c, Platform/Atomics/Source/SolidSyslogStdAtomicCounterStatic.c
Introduces private struct with atomic Value, vtable-style Initialise/Cleanup, and static pool-backed Create/Destroy mapping handles to pool indices.
WindowsAtomicCounter Pool Migration: Private, Impl, and Pool
Platform/Windows/Source/SolidSyslogWindowsAtomicCounterPrivate.h, Platform/Windows/Source/SolidSyslogWindowsAtomicCounter.c, Platform/Windows/Source/SolidSyslogWindowsAtomicCounterStatic.c
Adds Windows-specific private struct and vtable lifecycle, plus static pool-backed Create/Destroy using Windows interlocked operations.
FatFsFile Pool Migration: Header, Private, and Pool
Platform/FatFs/Interface/SolidSyslogFatFsFile.h, Platform/FatFs/Source/SolidSyslogFatFsFilePrivate.h, Platform/FatFs/Source/SolidSyslogFatFsFile.c, Platform/FatFs/Source/SolidSyslogFatFsFileStatic.c
Simplified public header to Create(void); added private struct with FIL and IsOpen, refactored Initialise/Cleanup, and static pool-backed Create/Destroy.
TlsStream Pool Migration: Header, Private, Impl, and Pool
Platform/OpenSsl/Interface/SolidSyslogTlsStream.h, Platform/OpenSsl/Source/SolidSyslogTlsStreamPrivate.h, Platform/OpenSsl/Source/SolidSyslogTlsStream.c, Platform/OpenSsl/Source/SolidSyslogTlsStreamStatic.c
Removed in-header storage, added private stream struct with OpenSSL objects, exported TlsStream_Initialise/Cleanup, and static pool-backed SolidSyslogTlsStream_Create/Destroy with null-stream fallback.
Test Infrastructure: Helper API and Fixture Updates
Tests/SolidSyslogAtomicCounterTestHelper.h, Tests/SolidSyslogStdAtomicCounterTestHelper.c, Tests/SolidSyslogWindowsAtomicCounterTestHelper.c, Tests/Fixtures/SmallMessageSizeTunables.h, Tests/CMakeLists.txt, Tests/FatFs/CMakeLists.txt
Test helpers switched to storage-less TestAtomicCounter_Create(), added TestAtomicCounter_PoolSize(), adjusted tunable overrides, registered new pool tests and linked fakes.
Pool Behavior Tests
Tests/SolidSyslogStdAtomicCounterPoolTest.cpp, Tests/SolidSyslogWindowsAtomicCounterPoolTest.cpp, Tests/FatFs/SolidSyslogFatFsFilePoolTest.cpp, Tests/SolidSyslogTlsStreamPoolTest.cpp
Added tests verifying pool exhaustion returns distinct fallback, error reporting, fallback behavior (e.g., Increment returns 1 or Send drops), config-lock acquisition patterns, and unknown/stale-destroy warnings.
Contract and Fixture Tests
Tests/SolidSyslogAtomicCounterContractTest.cpp, Tests/SolidSyslogMetaSdTest.cpp, Tests/SolidSyslogTest.cpp, Tests/FatFs/SolidSyslogFatFsFileTest.cpp, Tests/SolidSyslogTlsStreamTest.cpp
Updated contract tests to use pool-based Create(), added pool-size guard for two-counter independence, updated fixtures to own created counters/files and rely on fixture teardown.
Caller Site Updates: BDD Targets and Integration Tests
Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_*.c, Bdd/Targets/FreeRtos/main.c, Bdd/Targets/Linux/main.c, Bdd/Targets/Windows/BddTargetWindows.c, Tests/OpenSslIntegration/SolidSyslogTlsStreamIntegrationTest.cpp
All call sites updated to remove stack/static storage and use the new pool-backed Create APIs.

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related issues

  • #29: Migration of SolidSyslogTlsStream to pool-backed Create(config) and removal of storage parameter — related to TLS stream API/ABI changes in this PR.

Possibly related PRs

🐰 "I hopped through pools of code today,
Creators shrank, the allocators play;
When slots run out, I hum a steady one—
A tiny null counter, and tests now run. 🥕"

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/s11-09-atomics-tls-fatfs-sweep

@github-actions

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1282 passed, 🙈 2 skipped)
   🚦   build-freertos-host-tdd: 100% successful (✔️ 1445 passed, 🙈 2 skipped)
   🚦   build-linux-clang: 100% successful (✔️ 1234 passed, 🙈 2 skipped)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1234 passed, 🙈 2 skipped)
   🚦   integration-linux-openssl: 100% successful (✔️ 9 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 9 passed)
   🚦   bdd-linux-syslog-ng: 94% successful (✔️ 46 passed, 🙈 3 skipped)
   🚦   bdd-windows-otel: 90% successful (✔️ 44 passed, 🙈 5 skipped)
   🚦   bdd-freertos-qemu: 73% successful (✔️ 36 passed, 🙈 13 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1123 passed, 🙈 1 skipped)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1234 passed, 🙈 2 skipped)
   ⚠️   Clang-Tidy: 1 warning (normal: 1)
   ⚠️   CPPCheck: No warnings


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
CLAUDE.md (1)

341-393: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Reconcile allocation-model guidance in this document.

These rows now document pool-backed *_Create(void) correctly, but the later Storage injection section still presents caller-provided storage as the general rule. Please scope that section to classes that still use storage injection (or rewrite it as mixed-model migration guidance) to avoid contradictory contributor instructions.

📝 Suggested doc adjustment
-**Storage injection:**
-
-- Mirrors the `SolidSyslogFormatterStorage` pattern. The public header exposes an opaque storage
-  type and a `SOLIDSYSLOG_<TYPE>_STORAGE_SIZE` macro; `_Create` takes a pointer to caller-allocated
-  storage of that size. No `malloc` anywhere in the library.
+**Allocation model (during migration):**
+
+- The codebase currently uses two patterns:
+  - Storage-injection classes: public header exposes opaque storage and
+    `SOLIDSYSLOG_<TYPE>_STORAGE_SIZE`; `_Create` takes caller-provided storage.
+  - Pool-backed classes: `_Create(void)` allocates from fixed internal pools.
+- No `malloc` anywhere in the library.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLAUDE.md` around lines 341 - 393, The Storage injection section contradicts
the per-type pool-backed Create model documented for many headers (e.g.,
SolidSyslogTlsStream_Create, SolidSyslogSwitchingSender_Create,
SolidSyslogPassthroughBuffer_Create, SolidSyslogPosixMutex_Create,
SolidSyslogBlockStore_Create, SolidSyslogStdAtomicCounter_Create, etc.); update
that section to either (a) scope the “caller-provided storage” guidance only to
the few types that still require injected storage, listing those types
explicitly, or (b) replace it with a short “mixed-model migration” note
explaining that most current Create APIs use internal static pools and
describing how contributors should choose between pool-backed Create APIs and
the legacy storage-injection pattern when adding new types. Ensure the text
references the Create/_Destroy naming convention and the pool-exhaustion
fallback behavior so readers can reconcile both models.
Tests/SolidSyslogTest.cpp (1)

632-749: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Move pool-backed MetaSd resources to teardown-managed fixture state.

These tests create/destroy pool-backed handles inside the test body. If an assertion fails before cleanup, the pool slot can leak and cascade into unrelated failures later in the run. Please track these handles in fixture members and release them in teardown().

Based on learnings: In this codebase’s global-slot CppUTest test groups, use teardown()-only cleanup for per-test isolation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Tests/SolidSyslogTest.cpp` around lines 632 - 749, Tests currently create
pool-backed handles (e.g., via TestAtomicCounter_Create and
SolidSyslogMetaSd_Create) inside test bodies and destroy them there, which can
leak pool slots on assertion failure; instead, store created handles as fixture
members (e.g., AtomicCounter* counter_; SolidSyslogStructuredData* metaSd_;
SolidSyslogStructuredData* timeQuality_;) and assign them in each test, remove
per-test SolidSyslog_Destroy/SolidSyslog_Create calls from teardown
responsibility, and ensure teardown() always calls
SolidSyslogMetaSd_Destroy(metaSd_),
SolidSyslogTimeQualitySd_Destroy(timeQuality_) and
TestAtomicCounter_Destroy(counter_) (and resets config.Sd/config.SdCount) so
pool-backed resources are released even when assertions fail; update tests to
only set fixture members and let teardown() perform the cleanup.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@DEVLOG.md`:
- Around line 163-183: Update the mismatched CI count: change the header
sentence "Two CI-gated checks remain" to reflect the four listed checks (or
alternatively reduce the list to two items); specifically make the sentence
consistent with the enumerated checks build-windows-msvc, bdd-windows-otel,
analyze-iwyu, and bdd-freertos-qemu so the document header and the list match.

In `@Platform/OpenSsl/Source/SolidSyslogTlsStream.c`:
- Around line 68-76: TlsStream_Cleanup currently releases TLS objects then
overwrites the base without closing the transport; modify TlsStream_Cleanup to
first close the transport (call TlsStream_Close(self) or directly invoke
SolidSyslogStream_Close(self->Config.Transport)) before calling
TlsStream_ReleaseHandshakeState and TlsStream_ReleaseSslContext, and only after
those releases overwrite *base with the SolidSyslogNullStream_Get() vtable so
the underlying transport is guaranteed closed during destroy.

In `@Tests/SolidSyslogNullAtomicCounterTest.cpp`:
- Around line 10-14: Add an explicit assertion that the accessor returns a
non-null handle: in the TEST_GROUP setup where
SolidSyslogNullAtomicCounter_Get() is called (the setup method assigning
counter), call the accessor and assert the returned pointer/handle is not null
before storing it (referencing SolidSyslogNullAtomicCounter_Get and the setup
method / counter variable) so the API contract is enforced; similarly add the
same non-null assertion in the other test group(s) covering lines 19-28 to
ensure both groups validate the accessor directly.

---

Outside diff comments:
In `@CLAUDE.md`:
- Around line 341-393: The Storage injection section contradicts the per-type
pool-backed Create model documented for many headers (e.g.,
SolidSyslogTlsStream_Create, SolidSyslogSwitchingSender_Create,
SolidSyslogPassthroughBuffer_Create, SolidSyslogPosixMutex_Create,
SolidSyslogBlockStore_Create, SolidSyslogStdAtomicCounter_Create, etc.); update
that section to either (a) scope the “caller-provided storage” guidance only to
the few types that still require injected storage, listing those types
explicitly, or (b) replace it with a short “mixed-model migration” note
explaining that most current Create APIs use internal static pools and
describing how contributors should choose between pool-backed Create APIs and
the legacy storage-injection pattern when adding new types. Ensure the text
references the Create/_Destroy naming convention and the pool-exhaustion
fallback behavior so readers can reconcile both models.

In `@Tests/SolidSyslogTest.cpp`:
- Around line 632-749: Tests currently create pool-backed handles (e.g., via
TestAtomicCounter_Create and SolidSyslogMetaSd_Create) inside test bodies and
destroy them there, which can leak pool slots on assertion failure; instead,
store created handles as fixture members (e.g., AtomicCounter* counter_;
SolidSyslogStructuredData* metaSd_; SolidSyslogStructuredData* timeQuality_;)
and assign them in each test, remove per-test
SolidSyslog_Destroy/SolidSyslog_Create calls from teardown responsibility, and
ensure teardown() always calls SolidSyslogMetaSd_Destroy(metaSd_),
SolidSyslogTimeQualitySd_Destroy(timeQuality_) and
TestAtomicCounter_Destroy(counter_) (and resets config.Sd/config.SdCount) so
pool-backed resources are released even when assertions fail; update tests to
only set fixture members and let teardown() perform the cleanup.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e302c6a0-f652-4cca-88db-0aeddc4deeeb

📥 Commits

Reviewing files that changed from the base of the PR and between 986f325 and 0be6170.

📒 Files selected for processing (49)
  • Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_PosixTcp.c
  • Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_WinsockTcp.c
  • Bdd/Targets/FreeRtos/CMakeLists.txt
  • Bdd/Targets/FreeRtos/main.c
  • Bdd/Targets/Linux/main.c
  • Bdd/Targets/Windows/BddTargetWindows.c
  • CLAUDE.md
  • Core/Interface/SolidSyslogNullAtomicCounter.h
  • Core/Interface/SolidSyslogTunablesDefaults.h
  • Core/Source/CMakeLists.txt
  • Core/Source/SolidSyslogErrorMessages.h
  • Core/Source/SolidSyslogNullAtomicCounter.c
  • DEVLOG.md
  • Platform/Atomics/CMakeLists.txt
  • Platform/Atomics/Interface/SolidSyslogStdAtomicCounter.h
  • Platform/Atomics/Source/SolidSyslogStdAtomicCounter.c
  • Platform/Atomics/Source/SolidSyslogStdAtomicCounterPrivate.h
  • Platform/Atomics/Source/SolidSyslogStdAtomicCounterStatic.c
  • Platform/FatFs/Interface/SolidSyslogFatFsFile.h
  • Platform/FatFs/Source/SolidSyslogFatFsFile.c
  • Platform/FatFs/Source/SolidSyslogFatFsFilePrivate.h
  • Platform/FatFs/Source/SolidSyslogFatFsFileStatic.c
  • Platform/OpenSsl/CMakeLists.txt
  • Platform/OpenSsl/Interface/SolidSyslogTlsStream.h
  • Platform/OpenSsl/Source/SolidSyslogTlsStream.c
  • Platform/OpenSsl/Source/SolidSyslogTlsStreamPrivate.h
  • Platform/OpenSsl/Source/SolidSyslogTlsStreamStatic.c
  • Platform/Windows/CMakeLists.txt
  • Platform/Windows/Interface/SolidSyslogWindowsAtomicCounter.h
  • Platform/Windows/Source/SolidSyslogWindowsAtomicCounter.c
  • Platform/Windows/Source/SolidSyslogWindowsAtomicCounterPrivate.h
  • Platform/Windows/Source/SolidSyslogWindowsAtomicCounterStatic.c
  • Tests/CMakeLists.txt
  • Tests/FatFs/CMakeLists.txt
  • Tests/FatFs/SolidSyslogFatFsFilePoolTest.cpp
  • Tests/FatFs/SolidSyslogFatFsFileTest.cpp
  • Tests/Fixtures/SmallMessageSizeTunables.h
  • Tests/OpenSslIntegration/SolidSyslogTlsStreamIntegrationTest.cpp
  • Tests/SolidSyslogAtomicCounterContractTest.cpp
  • Tests/SolidSyslogAtomicCounterTestHelper.h
  • Tests/SolidSyslogMetaSdTest.cpp
  • Tests/SolidSyslogNullAtomicCounterTest.cpp
  • Tests/SolidSyslogStdAtomicCounterPoolTest.cpp
  • Tests/SolidSyslogStdAtomicCounterTestHelper.c
  • Tests/SolidSyslogTest.cpp
  • Tests/SolidSyslogTlsStreamPoolTest.cpp
  • Tests/SolidSyslogTlsStreamTest.cpp
  • Tests/SolidSyslogWindowsAtomicCounterPoolTest.cpp
  • Tests/SolidSyslogWindowsAtomicCounterTestHelper.c

Comment thread DEVLOG.md Outdated
Comment thread Platform/OpenSsl/Source/SolidSyslogTlsStream.c
Comment thread Tests/SolidSyslogNullAtomicCounterTest.cpp
DavidCozens and others added 4 commits May 20, 2026 16:36
CI analyze-format caught NamespaceIndentation drift. The local
pre-commit format check only saw files with staged changes, so the
new TEST_SOURCES entry slipped through the gcc-container test run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CodeRabbit feedback: the header sentence said "Two CI-gated checks
remain" but the enumerated list has four (build-windows-msvc,
bdd-windows-otel, analyze-iwyu, bdd-freertos-qemu).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CodeRabbit feedback on PR #415. Pre-existing behavior (preserved
verbatim by the S11.09 refactor): SolidSyslogTlsStream_Destroy
released SSL/BIO state but did not close the underlying transport.
A consumer who destroys a still-Open TlsStream leaks the transport
(socket / fd).

Cleanup now calls TlsStream_Close first, which:
- runs SSL_shutdown + ReleaseHandshakeState if Ssl != NULL (otherwise
  no-op), and
- always calls SolidSyslogStream_Close on the transport.

Close is idempotent on every Stream impl, so the normal
Open → Close → Destroy lifecycle is unaffected — the explicit Close
clears Ssl, and Cleanup's implicit Close then sees Ssl == NULL and
only re-closes the (already-closed, idempotent) transport.

Pinned by the new test SolidSyslogTlsStream::DestroyClosesTransportWhenStillOpen.
All 116 existing TlsStream unit tests + 9 OpenSSL integration tests
still pass; tidy / cppcheck / clang-format / IWYU clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CodeRabbit feedback on PR #415. Four SolidSyslog tests
(MetaSdProducesSequenceIdInStructuredData,
MetaSdSequenceIdIncrementsAcrossLogCalls, MsgFieldPreservedWithMetaSd,
MetaSdAndTimeQualitySdCoexistInSdArray) acquired pool-backed handles
(TestAtomicCounter, MetaSd, TimeQualitySd) as locals inside the test
body and Destroy'd them inline. With pool size 1U on each of those
classes, an assertion failure mid-body skips both Destroys and leaks
the slot, so the next test's Create returns the shared Null* fallback
and the cascade obscures the original failure.

Pre-S11.09 this couldn't happen because the storage was a stack-local
that vanished on test exit; the migration to pool-backed Create
introduced the leak window.

Move the handles to fixture members; setup nulls them; teardown
conditionally destroys whichever a test body assigned. Matches the
existing fixture pattern for `buffer` / `store` / `fakeSender`.

All 1277 tests still pass; tidy / cppcheck / clang-format / IWYU clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@DavidCozens

Copy link
Copy Markdown
Owner Author

Worked through the CodeRabbit review. Status:

# Finding Resolution
1 DEVLOG.md "Two CI-gated checks" should say "Four" Fixed9a8f361
2 TlsStream_Cleanup leaves transport open Fixed with test8954b11. Pre-existing behavior surfaced by CodeRabbit; not a S11.09 regression but worth correcting. New test DestroyClosesTransportWhenStillOpen pins the contract. Close is idempotent so the normal Open → Close → Destroy lifecycle is unaffected.
3 Add NullAtomicCounter::GetReturnsNonNullInstance test Skipped — reply on the inline comment. Pattern is inconsistent with the 11 sibling Null tests; the setup's Get() call already implicitly establishes the contract.
4 CLAUDE.md "Storage injection" section stale Deferred to S11.11 (MISRA D.002 storage-cast deviation cleanup). The section is genuinely stale post-S11.09 — only SolidSyslogFormatter and SolidSyslogAddress still use storage injection — but it's the same conceptual area as the MISRA deviation rows S11.11 will be touching, and the framing change reads better as part of that pass.
5 Pool-backed handles leak on assertion failure in SolidSyslogTest.cpp Fixedcd077c0. Lifted metaSdCounter, metaSd, timeQualitySd to TEST_GROUP fixture members; setup nulls them; teardown destroys whichever a test body assigned. Real concern introduced by the migration (pre-S11.09 the stack-local storage couldn't leak).

Plus a clang-format fix (eb06909) for the analyze-format CI failure from the first push.

All local gates green: debug + 1277 tests, sanitize, coverage, tidy, cppcheck, format, IWYU, OpenSSL integration (9/9).

@github-actions

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1283 passed, 🙈 2 skipped)
   🚦   build-freertos-host-tdd: 100% successful (✔️ 1446 passed, 🙈 2 skipped)
   🚦   build-linux-clang: 100% successful (✔️ 1235 passed, 🙈 2 skipped)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1235 passed, 🙈 2 skipped)
   🚦   integration-linux-openssl: 100% successful (✔️ 9 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 9 passed)
   🚦   bdd-linux-syslog-ng: 94% successful (✔️ 46 passed, 🙈 3 skipped)
   🚦   bdd-windows-otel: 90% successful (✔️ 44 passed, 🙈 5 skipped)
   🚦   bdd-freertos-qemu: 73% successful (✔️ 36 passed, 🙈 13 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1124 passed, 🙈 1 skipped)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1235 passed, 🙈 2 skipped)
   ⚠️   Clang-Tidy: 1 warning (normal: 1)
   ⚠️   CPPCheck: No warnings


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

@DavidCozens DavidCozens merged commit e4531e2 into main May 20, 2026
20 checks passed
@DavidCozens DavidCozens deleted the refactor/s11-09-atomics-tls-fatfs-sweep branch May 20, 2026 15:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

S11.09: Sweep — AtomicCounter family + TLS + FatFs onto PoolAllocator

1 participant