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 "SolidSyslogCircularBuffer.h"
6 : :
7 : : #include <stdbool.h>
8 : : #include <stddef.h>
9 : : #include <stdint.h>
10 : :
11 : : #include "SolidSyslogCircularBufferErrors.h"
12 : : #include "SolidSyslogCircularBufferPrivate.h"
13 : : #include "SolidSyslogError.h"
14 : : #include "SolidSyslogErrorCategory.h"
15 : : #include "SolidSyslogNullBuffer.h"
16 : : #include "SolidSyslogPoolAllocator.h"
17 : : #include "SolidSyslogPrival.h"
18 : : #include "SolidSyslogTunables.h"
19 : :
20 : : struct SolidSyslogBuffer;
21 : : struct SolidSyslogMutex;
22 : :
23 : : static inline size_t CircularBuffer_IndexFromHandle(const struct SolidSyslogBuffer* base);
24 : : static inline void CircularBuffer_CleanupAtIndex(size_t index, void* context);
25 : :
26 : : static bool CircularBuffer_InUse[SOLIDSYSLOG_CIRCULAR_BUFFER_POOL_SIZE];
27 : : static struct SolidSyslogCircularBuffer CircularBuffer_Pool[SOLIDSYSLOG_CIRCULAR_BUFFER_POOL_SIZE];
28 : : static struct SolidSyslogPoolAllocator CircularBuffer_Allocator = {
29 : : CircularBuffer_InUse,
30 : : SOLIDSYSLOG_CIRCULAR_BUFFER_POOL_SIZE
31 : : };
32 : :
33 : 244 : struct SolidSyslogBuffer* SolidSyslogCircularBuffer_Create(
34 : : struct SolidSyslogMutex* mutex,
35 : : uint8_t* ring,
36 : : size_t ringBytes,
37 : : SolidSyslogDiscardPolicyFunction getDiscardPolicy,
38 : : void* discardPolicyContext
39 : : )
40 : : {
41 : 244 : struct SolidSyslogBuffer* handle = SolidSyslogNullBuffer_Get();
42 [ + + ]: 244 : if (mutex == NULL)
43 : : {
44 : 3 : CircularBuffer_Report(
45 : : SOLIDSYSLOG_BAD_CONFIG_FATAL_SEVERITY,
46 : : SOLIDSYSLOG_CAT_BAD_CONFIG,
47 : : SOLIDSYSLOG_CIRCULAR_BUFFER_ERROR_NULL_MUTEX
48 : : );
49 : : }
50 [ + + ]: 241 : else if (ring == NULL)
51 : : {
52 : 3 : CircularBuffer_Report(
53 : : SOLIDSYSLOG_BAD_CONFIG_FATAL_SEVERITY,
54 : : SOLIDSYSLOG_CAT_BAD_CONFIG,
55 : : SOLIDSYSLOG_CIRCULAR_BUFFER_ERROR_NULL_RING
56 : : );
57 : : }
58 : : else
59 : : {
60 : 238 : size_t index = SolidSyslogPoolAllocator_AcquireFirstFree(&CircularBuffer_Allocator);
61 [ + + ]: 238 : if (SolidSyslogPoolAllocator_IndexIsValid(&CircularBuffer_Allocator, index))
62 : : {
63 : 234 : SolidSyslogCircularBuffer_Initialise(
64 : : &CircularBuffer_Pool[index].Base,
65 : : mutex,
66 : : ring,
67 : : ringBytes,
68 : : getDiscardPolicy,
69 : : discardPolicyContext
70 : : );
71 : 234 : handle = &CircularBuffer_Pool[index].Base;
72 : : }
73 : : else
74 : : {
75 : 4 : CircularBuffer_Report(
76 : : SOLIDSYSLOG_POOL_EXHAUSTED_SEVERITY,
77 : : SOLIDSYSLOG_CAT_POOL_EXHAUSTED,
78 : : SOLIDSYSLOG_CIRCULAR_BUFFER_ERROR_POOL_EXHAUSTED
79 : : );
80 : : }
81 : : }
82 : 244 : return handle;
83 : : }
84 : :
85 : 247 : void SolidSyslogCircularBuffer_Destroy(struct SolidSyslogBuffer* base)
86 : : {
87 : 247 : size_t index = CircularBuffer_IndexFromHandle(base);
88 : 247 : bool released =
89 [ + + + + ]: 482 : SolidSyslogPoolAllocator_IndexIsValid(&CircularBuffer_Allocator, index) &&
90 : 235 : SolidSyslogPoolAllocator_FreeIfInUse(&CircularBuffer_Allocator, index, CircularBuffer_CleanupAtIndex, NULL);
91 [ + + ]: 247 : if (!released)
92 : : {
93 : 13 : CircularBuffer_Report(
94 : : SOLIDSYSLOG_UNKNOWN_DESTROY_SEVERITY,
95 : : SOLIDSYSLOG_CAT_UNKNOWN_DESTROY,
96 : : SOLIDSYSLOG_CIRCULAR_BUFFER_ERROR_UNKNOWN_DESTROY
97 : : );
98 : : }
99 : 247 : }
100 : :
101 : 247 : static inline size_t CircularBuffer_IndexFromHandle(const struct SolidSyslogBuffer* base)
102 : : {
103 : 247 : size_t result = SOLIDSYSLOG_CIRCULAR_BUFFER_POOL_SIZE;
104 [ + + ]: 259 : for (size_t poolIndex = 0U; poolIndex < SOLIDSYSLOG_CIRCULAR_BUFFER_POOL_SIZE; poolIndex++)
105 : : {
106 [ + + ]: 247 : if (base == &CircularBuffer_Pool[poolIndex].Base)
107 : : {
108 : 235 : result = poolIndex;
109 : 235 : break;
110 : : }
111 : : }
112 : 247 : return result;
113 : : }
114 : :
115 : 234 : static inline void CircularBuffer_CleanupAtIndex(size_t index, void* context)
116 : : {
117 : : (void) context;
118 : 234 : SolidSyslogCircularBuffer_Cleanup(&CircularBuffer_Pool[index].Base);
119 : 234 : }
|