You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Portable in-memory ring buffer satisfying the SolidSyslogBuffer interface, suitable for bare-metal / RTOS targets without POSIX message queues, and as the buffer of choice for Windows.
Design
Storage: caller-supplied, Formatter-style variable-size pattern. Two sizing macros: SOLIDSYSLOG_CIRCULARBUFFER_STORAGE_SIZE(maxMessages) for the friendly "N max-sized messages" form, and SOLIDSYSLOG_CIRCULARBUFFER_STORAGE_SIZE_BYTES(ringBytes) for raw byte capacity (useful in tests). _Create takes storage, sizeof(storage), and the mutex. No internal malloc.
Record framing: each record is a uint16_t size header followed by size payload bytes. Records do not span the wrap point — wrap is handled by wrapPoint index and a no-split rule, not by record splitting. Payloads exceeding SOLIDSYSLOG_MAX_MESSAGE_SIZE are dropped at Write.
Overflow policy: drop-newest, silently. Matches the existing PosixMessageQueueBuffer (O_NONBLOCK + ignored mq_send return). Loss is detected SIEM-side by gaps in origin sequenceId (the mechanism that closed S04.06).
Read semantics: if the next record does not fit in the caller-supplied destination buffer, Read returns false with bytesRead = 0 and leaves the record queued — mirrors mq_receiveEMSGSIZE semantics.
Concurrency: synchronization via injected SolidSyslogMutex vtable (Lock/Unlock). SolidSyslogNullMutex is the no-op default for single-task use.
Parent epic: #6
Portable in-memory ring buffer satisfying the
SolidSyslogBufferinterface, suitable for bare-metal / RTOS targets without POSIX message queues, and as the buffer of choice for Windows.Design
SOLIDSYSLOG_CIRCULARBUFFER_STORAGE_SIZE(maxMessages)for the friendly "N max-sized messages" form, andSOLIDSYSLOG_CIRCULARBUFFER_STORAGE_SIZE_BYTES(ringBytes)for raw byte capacity (useful in tests)._Createtakesstorage,sizeof(storage), and the mutex. No internalmalloc.uint16_tsize header followed bysizepayload bytes. Records do not span the wrap point — wrap is handled bywrapPointindex and a no-split rule, not by record splitting. Payloads exceedingSOLIDSYSLOG_MAX_MESSAGE_SIZEare dropped atWrite.PosixMessageQueueBuffer(O_NONBLOCK+ ignoredmq_sendreturn). Loss is detected SIEM-side by gaps inorigin sequenceId(the mechanism that closed S04.06).ReadreturnsfalsewithbytesRead = 0and leaves the record queued — mirrorsmq_receiveEMSGSIZEsemantics.SolidSyslogMutexvtable (Lock/Unlock).SolidSyslogNullMutexis the no-op default for single-task use.Deliverables in this story
SolidSyslogCircularBuffer+ tests (main behaviour, mutex call-pattern, small-ring boundary tests)SolidSyslogMutexvtable +SolidSyslogNullMutex+ testsSolidSyslogPosixMutex(pthread_mutex_t) + testsSolidSyslogWindowsMutex(CRITICAL_SECTION) + testsCLAUDE.mdOut of scope
SolidSyslogDiscardPolicyfromBlockStore._Createinitialization-failure handling (pthread_mutex_init/InitializeCriticalSectionreturn values) — deferred to E12 (error handling), tracked in the project robustness backlog.