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 "lwip/opt.h"
6 : :
7 : : #if LWIP_SOCKET && LWIP_TCP && LWIP_SOCKET_SELECT
8 : :
9 : : #include "SolidSyslogLwipSocketTcpStream.h"
10 : :
11 : : #include <stdbool.h>
12 : : #include <stddef.h>
13 : : #include <stdint.h>
14 : :
15 : : #include "SolidSyslogError.h"
16 : : #include "SolidSyslogErrorCategory.h"
17 : : #include "SolidSyslogLwipSocketTcpStreamErrors.h"
18 : : #include "SolidSyslogLwipSocketTcpStreamPrivate.h"
19 : : #include "SolidSyslogNullStream.h"
20 : : #include "SolidSyslogPoolAllocator.h"
21 : : #include "SolidSyslogPrival.h"
22 : : #include "SolidSyslogTunables.h"
23 : :
24 : : struct SolidSyslogStream;
25 : :
26 : : static inline size_t LwipSocketTcpStream_IndexFromHandle(const struct SolidSyslogStream* base);
27 : : static inline void LwipSocketTcpStream_CleanupAtIndex(size_t index, void* context);
28 : :
29 : : static bool LwipSocketTcpStream_InUse[SOLIDSYSLOG_TCP_STREAM_POOL_SIZE];
30 : : static struct SolidSyslogLwipSocketTcpStream LwipSocketTcpStream_Pool[SOLIDSYSLOG_TCP_STREAM_POOL_SIZE];
31 : : static struct SolidSyslogPoolAllocator LwipSocketTcpStream_Allocator = {
32 : : LwipSocketTcpStream_InUse,
33 : : SOLIDSYSLOG_TCP_STREAM_POOL_SIZE
34 : : };
35 : :
36 : 70 : struct SolidSyslogStream* SolidSyslogLwipSocketTcpStream_Create(
37 : : const struct SolidSyslogLwipSocketTcpStreamConfig* config
38 : : )
39 : : {
40 : 70 : size_t index = SolidSyslogPoolAllocator_AcquireFirstFree(&LwipSocketTcpStream_Allocator);
41 : 70 : struct SolidSyslogStream* handle = SolidSyslogNullStream_Get();
42 [ + + ]: 70 : if (SolidSyslogPoolAllocator_IndexIsValid(&LwipSocketTcpStream_Allocator, index) == true)
43 : : {
44 : 67 : SolidSyslogLwipSocketTcpStream_Initialise(&LwipSocketTcpStream_Pool[index].Base, config);
45 : 67 : handle = &LwipSocketTcpStream_Pool[index].Base;
46 : : }
47 : : else
48 : : {
49 : 3 : LwipSocketTcpStream_Report(
50 : : SOLIDSYSLOG_POOL_EXHAUSTED_SEVERITY,
51 : : SOLIDSYSLOG_CAT_POOL_EXHAUSTED,
52 : : SOLIDSYSLOG_TCP_STREAM_ERROR_POOL_EXHAUSTED
53 : : );
54 : : }
55 : 70 : return handle;
56 : : }
57 : :
58 : 70 : void SolidSyslogLwipSocketTcpStream_Destroy(struct SolidSyslogStream* base)
59 : : {
60 : 70 : size_t index = LwipSocketTcpStream_IndexFromHandle(base);
61 [ + + + + ]: 138 : bool released = SolidSyslogPoolAllocator_IndexIsValid(&LwipSocketTcpStream_Allocator, index) &&
62 : 68 : SolidSyslogPoolAllocator_FreeIfInUse(
63 : : &LwipSocketTcpStream_Allocator,
64 : : index,
65 : : LwipSocketTcpStream_CleanupAtIndex,
66 : : NULL
67 : : );
68 [ + + ]: 70 : if (!released)
69 : : {
70 : 3 : LwipSocketTcpStream_Report(
71 : : SOLIDSYSLOG_UNKNOWN_DESTROY_SEVERITY,
72 : : SOLIDSYSLOG_CAT_UNKNOWN_DESTROY,
73 : : SOLIDSYSLOG_TCP_STREAM_ERROR_UNKNOWN_DESTROY
74 : : );
75 : : }
76 : 70 : }
77 : :
78 : 70 : static inline size_t LwipSocketTcpStream_IndexFromHandle(const struct SolidSyslogStream* base)
79 : : {
80 : 70 : size_t result = SOLIDSYSLOG_TCP_STREAM_POOL_SIZE;
81 [ + + ]: 77 : for (size_t poolIndex = 0U; poolIndex < SOLIDSYSLOG_TCP_STREAM_POOL_SIZE; poolIndex++)
82 : : {
83 [ + + ]: 75 : if (base == &LwipSocketTcpStream_Pool[poolIndex].Base)
84 : : {
85 : 68 : result = poolIndex;
86 : 68 : break;
87 : : }
88 : : }
89 : 70 : return result;
90 : : }
91 : :
92 : 67 : static inline void LwipSocketTcpStream_CleanupAtIndex(size_t index, void* context)
93 : : {
94 : : (void) context;
95 : 67 : SolidSyslogLwipSocketTcpStream_Cleanup(&LwipSocketTcpStream_Pool[index].Base);
96 : 67 : }
97 : :
98 : : #else
99 : :
100 : : /* ISO C forbids an empty translation unit. */
101 : : typedef int LwipSocketTcpStreamStatic_EmptyTranslationUnit;
102 : :
103 : : #endif /* LWIP_SOCKET && LWIP_TCP && LWIP_SOCKET_SELECT */
|