Skip to content

S24.20: SolidSyslogBuffer_Read conflates empty buffer with oversized-record stall #605

Description

@DavidCozens

Parent epic: #254

Context

Surfaced during the S23.02 public-header documentation pass (#248, PR #604).
Writing down SolidSyslogBuffer_Read's return contract exposed a genuine API
design gap; per S23.02's "inconsistencies surfaced during this pass are raised
as separate issues rather than papered over with prose" acceptance criterion,
tracking it here rather than fixing it in the docs PR.

Source: CodeRabbit review comment
#604 (comment)

The gap

bool SolidSyslogBuffer_Read(struct SolidSyslogBuffer* base, void* data, size_t maxSize, size_t* bytesRead)
returns false / bytesRead == 0 for two distinct conditions:

  1. The buffer is genuinely empty — nothing to deliver.
  2. The record at the head is larger than maxSize and cannot be copied out, so
    it is left un-dequeued.

SolidSyslog_Service's drain loop reads false as "empty, stop". In case (2)
the oversized record sits at the head indefinitely: the loop stops early on
every pass, the record is never delivered, and no SolidSyslog_Error is emitted
— a silent stall with no diagnostic and no caller-visible recovery path.

In normal operation maxSize (the servicing scratch buffer) is sized to the
maximum record, so this is latent rather than routinely hit — but it is
reachable via misconfiguration (a servicing buffer smaller than a producer's
max record) and is invisible when it happens.

Options to weigh (design, not prescribed)

  • Distinguish the two conditions via a tri-state result or an out-enum
    (EMPTY / DELIVERED / OVERSIZED).
  • Keep false but emit SolidSyslog_Error(..., _BUFFER_...) on the oversized
    case so the stall is at least observable.
  • Drop-and-advance the oversized head record (with an error) so the drain loop
    makes progress rather than wedging.

Done when

  • SolidSyslogBuffer_Read (and the SolidSyslogBuffer vtable contract) can no
    longer silently wedge the drain loop on an oversized head record.
  • The chosen behaviour is covered by a unit test for the oversized-head case
    against the concrete buffers (Circular, PosixMessageQueue) as applicable.
  • Contract doc-comments in SolidSyslogBuffer.h / SolidSyslogBufferDefinition.h
    updated to match the new behaviour.

Metadata

Metadata

Assignees

No one assigned

    Labels

    storyStory issue

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions