SolidSyslog coverage report
Current view: top level - Core/Source - SolidSyslogPendingEvents.c (source / functions) Coverage Total Hit
Test: SolidSyslog Lines: 100.0 % 59 59
Test Date: 2026-11-12 23:14:35 Functions: 100.0 % 8 8
Branches: 100.0 % 24 24

             Branch data     Line data    Source code
       1                 :             : /* SPDX-FileCopyrightText: Copyright 2026 Cozens Software Solutions Limited
       2                 :             :  * SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 OR LicenseRef-PolyForm-Internal-Use-1.0.0 OR LicenseRef-COSOSO-Commercial
       3                 :             :  */
       4                 :             : 
       5                 :             : #include "SolidSyslogPendingEvents.h"
       6                 :             : 
       7                 :             : #include <stdbool.h>
       8                 :             : #include <stddef.h>
       9                 :             : #include <stdint.h>
      10                 :             : 
      11                 :             : #include "SolidSyslogBufferCategories.h"
      12                 :             : #include "SolidSyslogError.h"
      13                 :             : #include "SolidSyslogFileCategories.h"
      14                 :             : #include "SolidSyslogLoggerCategories.h"
      15                 :             : #include "SolidSyslogSecurityPolicyCategories.h"
      16                 :             : #include "SolidSyslogSenderCategories.h"
      17                 :             : #include "SolidSyslogStoreCategories.h"
      18                 :             : #include "SolidSyslogTlsStreamCategories.h"
      19                 :             : 
      20                 :             : struct PendingEventSlot
      21                 :             : {
      22                 :             :     const struct SolidSyslogErrorSource* Source;
      23                 :             :     int32_t Detail;
      24                 :             :     int32_t NativeCode;
      25                 :             :     /* The event's position in PendingEvents_Severities plus one. Zero, where a
      26                 :             :      * slot starts and where Clear returns it, stands for the kind's own
      27                 :             :      * severity, so a slot read before its first event lands says nothing
      28                 :             :      * more severe than its kind is raised at. */
      29                 :             :     uint8_t SeverityCode;
      30                 :             :     bool HasNativeCode;
      31                 :             :     bool Pending;
      32                 :             : };
      33                 :             : 
      34                 :             : /* A reported kind and the least severe severity it is raised at. */
      35                 :             : struct PendingEventKind
      36                 :             : {
      37                 :             :     uint16_t Category;
      38                 :             :     enum SolidSyslogSeverity Severity;
      39                 :             : };
      40                 :             : 
      41                 :             : /* The reported kinds, in slot order. Index is identity: Take reports the
      42                 :             :  * category from this table, so a slot never has to store it. The causes come
      43                 :             :  * first, then the losses they lead to, then the halt a loss can end in, then
      44                 :             :  * the delivery state, so a reader walking the slots in order reports a cause
      45                 :             :  * ahead of what it caused: a file fault ahead of the freeze, a threshold
      46                 :             :  * crossed ahead of the full store's refusal, that refusal ahead of the halt, a
      47                 :             :  * refused handshake ahead of the failed delivery. */
      48                 :             : static const struct PendingEventKind PendingEvents_Kinds[SOLIDSYSLOG_PENDING_EVENT_KIND_COUNT] = {
      49                 :             :     {SOLIDSYSLOG_CAT_FILE_IO_FAILED, SOLIDSYSLOG_SEVERITY_ERROR},
      50                 :             :     {SOLIDSYSLOG_CAT_SECURITY_POLICY_KEY_UNAVAILABLE, SOLIDSYSLOG_SEVERITY_ERROR},
      51                 :             :     {SOLIDSYSLOG_CAT_SECURITY_POLICY_SEAL_FAILED, SOLIDSYSLOG_SEVERITY_ERROR},
      52                 :             :     {SOLIDSYSLOG_CAT_SECURITY_POLICY_OPEN_FAILED, SOLIDSYSLOG_SEVERITY_ERROR},
      53                 :             :     {SOLIDSYSLOG_CAT_TLS_STREAM_HANDSHAKE_FAILED, SOLIDSYSLOG_SEVERITY_WARNING},
      54                 :             :     {SOLIDSYSLOG_CAT_BUFFER_BACKEND_FAILED, SOLIDSYSLOG_SEVERITY_ERROR},
      55                 :             :     {SOLIDSYSLOG_CAT_BUFFER_RECORDS_LOST, SOLIDSYSLOG_SEVERITY_WARNING},
      56                 :             :     {SOLIDSYSLOG_CAT_STORE_THRESHOLD_CROSSED, SOLIDSYSLOG_SEVERITY_WARNING},
      57                 :             :     {SOLIDSYSLOG_CAT_STORE_RECORDS_LOST, SOLIDSYSLOG_SEVERITY_WARNING},
      58                 :             :     {SOLIDSYSLOG_CAT_STORE_RECORD_DISCARDED, SOLIDSYSLOG_SEVERITY_ERROR},
      59                 :             :     {SOLIDSYSLOG_CAT_STORE_WRITE_FAILED, SOLIDSYSLOG_SEVERITY_ERROR},
      60                 :             :     {SOLIDSYSLOG_CAT_STORE_FROZEN, SOLIDSYSLOG_SEVERITY_ERROR},
      61                 :             :     {SOLIDSYSLOG_CAT_SENDER_RECORDS_LOST, SOLIDSYSLOG_SEVERITY_ERROR},
      62                 :             :     {SOLIDSYSLOG_CAT_LOGGER_HALTED, SOLIDSYSLOG_SEVERITY_ERROR},
      63                 :             :     {SOLIDSYSLOG_CAT_SENDER_DELIVERY_FAILED, SOLIDSYSLOG_SEVERITY_WARNING},
      64                 :             :     {SOLIDSYSLOG_CAT_SENDER_DELIVERY_RESTORED, SOLIDSYSLOG_SEVERITY_NOTICE},
      65                 :             : };
      66                 :             : 
      67                 :             : /* The severities in RFC 5424 order, which a slot's code indexes. */
      68                 :             : static const enum SolidSyslogSeverity PendingEvents_Severities[] = {
      69                 :             :     SOLIDSYSLOG_SEVERITY_EMERGENCY,
      70                 :             :     SOLIDSYSLOG_SEVERITY_ALERT,
      71                 :             :     SOLIDSYSLOG_SEVERITY_CRITICAL,
      72                 :             :     SOLIDSYSLOG_SEVERITY_ERROR,
      73                 :             :     SOLIDSYSLOG_SEVERITY_WARNING,
      74                 :             :     SOLIDSYSLOG_SEVERITY_NOTICE,
      75                 :             :     SOLIDSYSLOG_SEVERITY_INFORMATIONAL,
      76                 :             :     SOLIDSYSLOG_SEVERITY_DEBUG,
      77                 :             : };
      78                 :             : 
      79                 :             : static volatile struct PendingEventSlot PendingEvents_Slots[SOLIDSYSLOG_PENDING_EVENT_KIND_COUNT];
      80                 :             : 
      81                 :             : static inline size_t PendingEvents_IndexOf(uint16_t category);
      82                 :             : static inline uint8_t PendingEvents_SeverityCode(enum SolidSyslogSeverity severity);
      83                 :             : static inline enum SolidSyslogSeverity PendingEvents_SeverityOf(const struct PendingEventKind* kind, uint8_t code);
      84                 :             : 
      85                 :        9292 : void SolidSyslogPendingEvents_Record(const struct SolidSyslogErrorEvent* event)
      86                 :             : {
      87                 :        9292 :     size_t index = PendingEvents_IndexOf(event->Category);
      88         [ +  + ]:        9292 :     if (index < SOLIDSYSLOG_PENDING_EVENT_KIND_COUNT)
      89                 :             :     {
      90                 :        7729 :         volatile struct PendingEventSlot* slot = &PendingEvents_Slots[index];
      91                 :             :         /* Volatile stores, Pending last: the header states what that buys. */
      92                 :        7729 :         slot->SeverityCode = PendingEvents_SeverityCode(event->Severity);
      93                 :        7729 :         slot->Source = event->Source;
      94                 :        7729 :         slot->Detail = event->Detail;
      95                 :        7729 :         slot->NativeCode = event->NativeCode;
      96                 :        7729 :         slot->HasNativeCode = event->HasNativeCode;
      97                 :        7729 :         slot->Pending = true;
      98                 :             :     }
      99                 :        9292 : }
     100                 :             : 
     101                 :             : /* The slot index of a reported kind, or SOLIDSYSLOG_PENDING_EVENT_KIND_COUNT for
     102                 :             :  * a category that is not one. */
     103                 :        9292 : static inline size_t PendingEvents_IndexOf(uint16_t category)
     104                 :             : {
     105                 :        9292 :     size_t found = SOLIDSYSLOG_PENDING_EVENT_KIND_COUNT;
     106                 :        9292 :     for (size_t index = 0U;
     107   [ +  +  +  + ]:      113142 :          (index < SOLIDSYSLOG_PENDING_EVENT_KIND_COUNT) && (found == SOLIDSYSLOG_PENDING_EVENT_KIND_COUNT);
     108                 :      103850 :          index++)
     109                 :             :     {
     110         [ +  + ]:      103850 :         if (PendingEvents_Kinds[index].Category == category)
     111                 :             :         {
     112                 :        7729 :             found = index;
     113                 :             :         }
     114                 :             :     }
     115                 :        9292 :     return found;
     116                 :             : }
     117                 :             : 
     118                 :             : /* A severity the table does not hold keeps code zero, the kind's own. */
     119                 :        7729 : static inline uint8_t PendingEvents_SeverityCode(enum SolidSyslogSeverity severity)
     120                 :             : {
     121                 :        7729 :     const size_t severityCount = sizeof(PendingEvents_Severities) / sizeof(PendingEvents_Severities[0]);
     122                 :        7729 :     uint8_t code = 0U;
     123         [ +  + ]:       69561 :     for (size_t position = 0U; position < severityCount; position++)
     124                 :             :     {
     125         [ +  + ]:       61832 :         if (PendingEvents_Severities[position] == severity)
     126                 :             :         {
     127                 :        7729 :             code = (uint8_t) (position + 1U);
     128                 :             :         }
     129                 :             :     }
     130                 :        7729 :     return code;
     131                 :             : }
     132                 :             : 
     133                 :       58652 : bool SolidSyslogPendingEvents_IsPending(size_t index)
     134                 :             : {
     135                 :       58652 :     bool pending = false;
     136         [ +  + ]:       58652 :     if (index < SOLIDSYSLOG_PENDING_EVENT_KIND_COUNT)
     137                 :             :     {
     138                 :       58651 :         pending = PendingEvents_Slots[index].Pending;
     139                 :             :     }
     140                 :       58652 :     return pending;
     141                 :             : }
     142                 :             : 
     143                 :         728 : bool SolidSyslogPendingEvents_AnyPending(void)
     144                 :             : {
     145                 :         728 :     bool pending = false;
     146   [ +  +  +  + ]:       12143 :     for (size_t index = 0U; (index < SOLIDSYSLOG_PENDING_EVENT_KIND_COUNT) && !pending; index++)
     147                 :             :     {
     148                 :       11415 :         pending = PendingEvents_Slots[index].Pending;
     149                 :             :     }
     150                 :         728 :     return pending;
     151                 :             : }
     152                 :             : 
     153                 :         987 : bool SolidSyslogPendingEvents_Take(size_t index, struct SolidSyslogErrorEvent* event)
     154                 :             : {
     155                 :         987 :     bool wasPending = false;
     156         [ +  + ]:         987 :     if (index < SOLIDSYSLOG_PENDING_EVENT_KIND_COUNT)
     157                 :             :     {
     158                 :         986 :         volatile struct PendingEventSlot* slot = &PendingEvents_Slots[index];
     159                 :         986 :         wasPending = slot->Pending;
     160                 :         986 :         slot->Pending = false;
     161                 :         986 :         event->Severity = PendingEvents_SeverityOf(&PendingEvents_Kinds[index], slot->SeverityCode);
     162                 :         986 :         event->Category = PendingEvents_Kinds[index].Category;
     163                 :         986 :         event->HasNativeCode = slot->HasNativeCode;
     164                 :         986 :         event->Source = slot->Source;
     165                 :         986 :         event->Detail = slot->Detail;
     166                 :         986 :         event->NativeCode = slot->NativeCode;
     167                 :             :     }
     168                 :         987 :     return wasPending;
     169                 :             : }
     170                 :             : 
     171                 :             : /* A nonzero code comes only from PendingEvents_SeverityCode, so it is always
     172                 :             :  * a position in the table plus one. */
     173                 :         986 : static inline enum SolidSyslogSeverity PendingEvents_SeverityOf(const struct PendingEventKind* kind, uint8_t code)
     174                 :             : {
     175                 :         986 :     enum SolidSyslogSeverity severity = kind->Severity;
     176         [ +  + ]:         986 :     if (code > 0U)
     177                 :             :     {
     178                 :         621 :         severity = PendingEvents_Severities[code - 1U];
     179                 :             :     }
     180                 :         986 :     return severity;
     181                 :             : }
     182                 :             : 
     183                 :        2789 : void SolidSyslogPendingEvents_Clear(void)
     184                 :             : {
     185         [ +  + ]:       47413 :     for (size_t index = 0U; index < SOLIDSYSLOG_PENDING_EVENT_KIND_COUNT; index++)
     186                 :             :     {
     187                 :       44624 :         PendingEvents_Slots[index].Pending = false;
     188                 :       44624 :         PendingEvents_Slots[index].SeverityCode = 0U;
     189                 :             :     }
     190                 :        2789 : }
        

Generated by: LCOV version 2.0-1