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 "SolidSyslogPosixMutex.h"
6 : :
7 : : #include <pthread.h>
8 : : #include <stddef.h>
9 : :
10 : : #include "SolidSyslogError.h"
11 : : #include "SolidSyslogMutexDefinition.h"
12 : : #include "SolidSyslogNullMutex.h"
13 : : #include "SolidSyslogPosixMutexErrors.h"
14 : : #include "SolidSyslogPosixMutexPrivate.h"
15 : :
16 : : const struct SolidSyslogErrorSource SolidSyslogPosixMutexErrorSource = {"PosixMutex", SolidSyslogMutexErrors_Name};
17 : :
18 : : static void PosixMutex_Lock(struct SolidSyslogMutex* base);
19 : : static void PosixMutex_Unlock(struct SolidSyslogMutex* base);
20 : :
21 : : static inline struct SolidSyslogPosixMutex* PosixMutex_SelfFromBase(struct SolidSyslogMutex* base);
22 : :
23 : 12 : void SolidSyslogPosixMutex_Initialise(struct SolidSyslogMutex* base)
24 : : {
25 : 12 : struct SolidSyslogPosixMutex* self = PosixMutex_SelfFromBase(base);
26 [ + - ]: 12 : if (pthread_mutex_init(&self->Mutex, NULL) == 0)
27 : : {
28 : 12 : self->Base.Lock = PosixMutex_Lock;
29 : 12 : self->Base.Unlock = PosixMutex_Unlock;
30 : : }
31 : : else
32 : : {
33 : : /* pthread_mutex_init failed (ENOMEM, EAGAIN). Install the shared
34 : : * NullMutex vtable so Lock/Unlock are safe no-ops; Cleanup will
35 : : * see the marker and skip pthread_mutex_destroy on the
36 : : * uninitialised native handle. */
37 : 0 : *base = *SolidSyslogNullMutex_Get();
38 : : }
39 : 12 : }
40 : :
41 : 12 : void SolidSyslogPosixMutex_Cleanup(struct SolidSyslogMutex* base)
42 : : {
43 : 12 : struct SolidSyslogPosixMutex* self = PosixMutex_SelfFromBase(base);
44 [ + - ]: 12 : if (self->Base.Lock == PosixMutex_Lock)
45 : : {
46 : 12 : pthread_mutex_destroy(&self->Mutex);
47 : : }
48 : : /* Overwrite the abstract base with the shared NullMutex vtable so
49 : : * use-after-destroy is a safe no-op rather than a NULL-fn-pointer crash. */
50 : 12 : *base = *SolidSyslogNullMutex_Get();
51 : 12 : }
52 : :
53 : 30 : static inline struct SolidSyslogPosixMutex* PosixMutex_SelfFromBase(struct SolidSyslogMutex* base)
54 : : {
55 : 30 : return (struct SolidSyslogPosixMutex*) base;
56 : : }
57 : :
58 : 3 : static void PosixMutex_Lock(struct SolidSyslogMutex* base)
59 : : {
60 : 3 : struct SolidSyslogPosixMutex* self = PosixMutex_SelfFromBase(base);
61 : 3 : pthread_mutex_lock(&self->Mutex);
62 : 3 : }
63 : :
64 : 3 : static void PosixMutex_Unlock(struct SolidSyslogMutex* base)
65 : : {
66 : 3 : struct SolidSyslogPosixMutex* self = PosixMutex_SelfFromBase(base);
67 : 3 : pthread_mutex_unlock(&self->Mutex);
68 : 3 : }
|