1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2022 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QSYSTEMSEMAPHORE_P_H
6#define QSYSTEMSEMAPHORE_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include "qsystemsemaphore.h"
20
21#if QT_CONFIG(systemsemaphore)
22
23#include "qcoreapplication.h"
24#include "qtipccommon_p.h"
25#include "private/qtcore-config_p.h"
26
27#include <sys/types.h>
28#if QT_CONFIG(posix_sem)
29# include <semaphore.h>
30#endif
31#ifndef SEM_FAILED
32# define SEM_FAILED nullptr
33struct sem_t;
34#endif
35#if QT_CONFIG(sysv_sem)
36# include <sys/sem.h>
37#endif
38
39QT_BEGIN_NAMESPACE
40
41class QSystemSemaphorePrivate;
42
43struct QSystemSemaphorePosix
44{
45 static constexpr bool Enabled = QT_CONFIG(posix_sem);
46 static bool supports(QNativeIpcKey::Type type)
47 { return type == QNativeIpcKey::Type::PosixRealtime; }
48 static bool runtimeSupportCheck();
49
50 bool handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode);
51 void cleanHandle(QSystemSemaphorePrivate *self);
52 bool modifySemaphore(QSystemSemaphorePrivate *self, int count);
53
54 sem_t *semaphore = SEM_FAILED;
55 bool createdSemaphore = false;
56};
57
58struct QSystemSemaphoreSystemV
59{
60 static constexpr bool Enabled = QT_CONFIG(sysv_sem);
61 static bool supports(QNativeIpcKey::Type type)
62 { return quint16(type) <= 0xff; }
63 static bool runtimeSupportCheck();
64
65#if QT_CONFIG(sysv_sem)
66 key_t handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode);
67 void cleanHandle(QSystemSemaphorePrivate *self);
68 bool modifySemaphore(QSystemSemaphorePrivate *self, int count);
69
70 QByteArray nativeKeyFile;
71 key_t unix_key = -1;
72 int semaphore = -1;
73 bool createdFile = false;
74 bool createdSemaphore = false;
75#endif
76};
77
78struct QSystemSemaphoreWin32
79{
80#ifdef Q_OS_WIN32
81 static constexpr bool Enabled = true;
82#else
83 static constexpr bool Enabled = false;
84#endif
85 static bool supports(QNativeIpcKey::Type type)
86 { return type == QNativeIpcKey::Type::Windows; }
87 static bool runtimeSupportCheck() { return Enabled; }
88
89 // we can declare the members without the #if
90 Qt::HANDLE handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode);
91 void cleanHandle(QSystemSemaphorePrivate *self);
92 bool modifySemaphore(QSystemSemaphorePrivate *self, int count);
93
94 Qt::HANDLE semaphore = nullptr;
95};
96
97class QSystemSemaphorePrivate
98{
99public:
100 QSystemSemaphorePrivate(QNativeIpcKey::Type type) : nativeKey(type)
101 { constructBackend(); }
102 ~QSystemSemaphorePrivate() { destructBackend(); }
103
104 void setWindowsErrorString(QLatin1StringView function); // Windows only
105 void setUnixErrorString(QLatin1StringView function);
106 inline void setError(QSystemSemaphore::SystemSemaphoreError e, const QString &message)
107 { error = e; errorString = message; }
108 inline void clearError()
109 { setError(e: QSystemSemaphore::NoError, message: QString()); }
110
111 QNativeIpcKey nativeKey;
112 QString errorString;
113 int initialValue;
114 QSystemSemaphore::SystemSemaphoreError error = QSystemSemaphore::NoError;
115
116 union Backend {
117 Backend() {}
118 ~Backend() {}
119 QSystemSemaphorePosix posix;
120 QSystemSemaphoreSystemV sysv;
121 QSystemSemaphoreWin32 win32;
122 };
123 QtIpcCommon::IpcStorageVariant<&Backend::posix, &Backend::sysv, &Backend::win32> backend;
124
125 void constructBackend();
126 void destructBackend();
127
128 template <typename Lambda> auto visit(const Lambda &lambda)
129 {
130 return backend.visit(nativeKey.type(), lambda);
131 }
132
133 void handle(QSystemSemaphore::AccessMode mode)
134 {
135 visit(lambda: [&](auto p) { p->handle(this, mode); });
136 }
137 void cleanHandle()
138 {
139 visit(lambda: [&](auto p) { p->cleanHandle(this); });
140 }
141 bool modifySemaphore(int count)
142 {
143 return visit(lambda: [&](auto p) { return p->modifySemaphore(this, count); });
144 }
145};
146
147QT_END_NAMESPACE
148
149#endif // QT_CONFIG(systemsemaphore)
150
151#endif // QSYSTEMSEMAPHORE_P_H
152
153

source code of qtbase/src/corelib/ipc/qsystemsemaphore_p.h