Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsharedmemory_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QSHAREDMEMORY_P_H
5#define QSHAREDMEMORY_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qsharedmemory.h"
19
20#include <QtCore/qstring.h>
21
22#if QT_CONFIG(sharedmemory)
23#include "qsystemsemaphore.h"
24#include "qtipccommon_p.h"
25#include "private/qobject_p.h"
26
27#if QT_CONFIG(posix_shm)
28# include <sys/mman.h>
29#endif
30#if QT_CONFIG(sysv_shm)
31# include <sys/shm.h>
32#endif
33
34QT_BEGIN_NAMESPACE
35
36class QSharedMemoryPrivate;
37
38#if QT_CONFIG(systemsemaphore)
39/*!
40 Helper class
41 */
42class QSharedMemoryLocker
43{
44 Q_DISABLE_COPY(QSharedMemoryLocker)
45public:
46 Q_NODISCARD_CTOR explicit QSharedMemoryLocker(QSharedMemory *sharedMemory)
47 : q_sm(sharedMemory)
48 {
49 Q_ASSERT(q_sm);
50 }
51
52 Q_NODISCARD_CTOR QSharedMemoryLocker(QSharedMemoryLocker &&other) noexcept
53 : q_sm{std::exchange(other.q_sm, nullptr)}
54 {}
55
56 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QSharedMemoryLocker)
57
58 void swap(QSharedMemoryLocker &other) noexcept
59 { qt_ptr_swap(q_sm, other.q_sm); }
60
61 inline ~QSharedMemoryLocker()
62 {
63 if (q_sm)
64 q_sm->unlock();
65 }
66
67 inline bool lock()
68 {
69 if (q_sm && q_sm->lock())
70 return true;
71 q_sm = nullptr;
72 return false;
73 }
74
75private:
76 friend void swap(QSharedMemoryLocker &lhs, QSharedMemoryLocker &rhs) noexcept
77 { lhs.swap(rhs); }
78
79 QSharedMemory *q_sm;
80};
81#endif // QT_CONFIG(systemsemaphore)
82
83class QSharedMemoryPosix
84{
85public:
86 static constexpr bool Enabled = QT_CONFIG(posix_shm);
87 static bool supports(QNativeIpcKey::Type type)
88 { return type == QNativeIpcKey::Type::PosixRealtime; }
89 static bool runtimeSupportCheck();
90
91 bool handle(QSharedMemoryPrivate *self);
92 bool cleanHandle(QSharedMemoryPrivate *self);
93 bool create(QSharedMemoryPrivate *self, qsizetype size);
94 bool attach(QSharedMemoryPrivate *self, QSharedMemory::AccessMode mode);
95 bool detach(QSharedMemoryPrivate *self);
96
97 int hand = -1;
98};
99
100class QSharedMemorySystemV
101{
102public:
103 static constexpr bool Enabled = QT_CONFIG(sysv_shm);
104 static bool supports(QNativeIpcKey::Type type)
105 { return quint16(type) <= 0xff; }
106 static bool runtimeSupportCheck();
107
108#if QT_CONFIG(sysv_shm)
109 key_t handle(QSharedMemoryPrivate *self);
110 bool cleanHandle(QSharedMemoryPrivate *self);
111 bool create(QSharedMemoryPrivate *self, qsizetype size);
112 bool attach(QSharedMemoryPrivate *self, QSharedMemory::AccessMode mode);
113 bool detach(QSharedMemoryPrivate *self);
114
115private:
116 void updateNativeKeyFile(const QNativeIpcKey &nativeKey);
117
118 QByteArray nativeKeyFile;
119 key_t unix_key = 0;
120#endif
121};
122
123class QSharedMemoryWin32
124{
125public:
126#ifdef Q_OS_WIN32
127 static constexpr bool Enabled = true;
128#else
129 static constexpr bool Enabled = false;
130#endif
131 static bool runtimeSupportCheck() { return Enabled; }
132 static bool supports(QNativeIpcKey::Type type)
133 { return type == QNativeIpcKey::Type::Windows; }
134
135 Qt::HANDLE handle(QSharedMemoryPrivate *self);
136 bool cleanHandle(QSharedMemoryPrivate *self);
137 bool create(QSharedMemoryPrivate *self, qsizetype size);
138 bool attach(QSharedMemoryPrivate *self, QSharedMemory::AccessMode mode);
139 bool detach(QSharedMemoryPrivate *self);
140
141 Qt::HANDLE hand = nullptr;
142};
143
144class Q_AUTOTEST_EXPORT QSharedMemoryPrivate : public QObjectPrivate
145{
146 Q_DECLARE_PUBLIC(QSharedMemory)
147
148public:
149 QSharedMemoryPrivate(QNativeIpcKey::Type type) : nativeKey(type)
150 { constructBackend(); }
151 ~QSharedMemoryPrivate();
152
153 void *memory = nullptr;
154 qsizetype size = 0;
155 QNativeIpcKey nativeKey;
156 QString errorString;
157#if QT_CONFIG(systemsemaphore)
158 using SemaphoreAccessMode = QSystemSemaphore::AccessMode;
159 QSystemSemaphore systemSemaphore{ QNativeIpcKey() };
160 bool lockedByMe = false;
161#else
162 enum SemaphoreAccessMode {};
163#endif
164 QSharedMemory::SharedMemoryError error = QSharedMemory::NoError;
165
166 union Backend {
167 Backend() {}
168 ~Backend() {}
169 QSharedMemoryPosix posix;
170 QSharedMemorySystemV sysv;
171 QSharedMemoryWin32 win32;
172 };
173 QtIpcCommon::IpcStorageVariant<&Backend::posix, &Backend::sysv, &Backend::win32> backend;
174
175 void constructBackend();
176 void destructBackend();
177 bool initKey(SemaphoreAccessMode mode);
178
179 template <typename Lambda> auto visit(const Lambda &lambda)
180 {
181 return backend.visit(nativeKey.type(), lambda);
182 }
183
184 bool handle()
185 {
186 return visit([&](auto p) { return !!p->handle(this); });
187 }
188 bool cleanHandle()
189 {
190 return visit([&](auto p) { return p->cleanHandle(this); });
191 }
192 bool create(qsizetype sz)
193 {
194 return visit([&](auto p) { return p->create(this, sz); });
195 }
196 bool attach(QSharedMemory::AccessMode mode)
197 {
198 return visit([&](auto p) { return p->attach(this, mode); });
199 }
200 bool detach()
201 {
202 return visit([&](auto p) { return p->detach(this); });
203 }
204
205 inline void setError(QSharedMemory::SharedMemoryError e, const QString &message)
206 { error = e; errorString = message; }
207 void setUnixErrorString(QLatin1StringView function);
208 void setWindowsErrorString(QLatin1StringView function);
209
210#if QT_CONFIG(systemsemaphore)
211 bool tryLocker(QSharedMemoryLocker *locker, const QString &function) {
212 if (!locker->lock()) {
213 errorString = QSharedMemory::tr("%1: unable to lock").arg(function);
214 error = QSharedMemory::LockError;
215 return false;
216 }
217 return true;
218 }
219 QNativeIpcKey semaphoreNativeKey() const;
220#endif // QT_CONFIG(systemsemaphore)
221};
222
223QT_END_NAMESPACE
224
225#endif // QT_CONFIG(sharedmemory)
226
227#endif // QSHAREDMEMORY_P_H
\inmodule QtSql
Combined button and popup list for selecting options.