5#ifndef QSHAREDMEMORY_P_H
6#define QSHAREDMEMORY_P_H
21#include <QtCore/qstring.h>
23#if QT_CONFIG(sharedmemory)
24#include "qsystemsemaphore.h"
25#include "qtipccommon_p.h"
26#include "private/qobject_p.h"
28#if QT_CONFIG(posix_shm)
31#if QT_CONFIG(sysv_shm)
37class QSharedMemoryPrivate;
39#if QT_CONFIG(systemsemaphore)
41
42
43class QSharedMemoryLocker
45 Q_DISABLE_COPY(QSharedMemoryLocker)
47 Q_NODISCARD_CTOR
explicit QSharedMemoryLocker(QSharedMemory *sharedMemory)
53 Q_NODISCARD_CTOR QSharedMemoryLocker(QSharedMemoryLocker &&other)
noexcept
54 : q_sm{std::exchange(other.q_sm,
nullptr)}
57 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QSharedMemoryLocker)
59 void swap(QSharedMemoryLocker &other)
noexcept
60 { qt_ptr_swap(q_sm, other.q_sm); }
62 inline ~QSharedMemoryLocker()
70 if (q_sm && q_sm->lock())
77 friend void swap(QSharedMemoryLocker &lhs, QSharedMemoryLocker &rhs)
noexcept
84class QSharedMemoryPosix
87 static constexpr bool Enabled = QT_CONFIG(posix_shm);
88 static bool supports(QNativeIpcKey::Type type)
89 {
return type == QNativeIpcKey::Type::PosixRealtime; }
90 static bool runtimeSupportCheck();
92 bool handle(QSharedMemoryPrivate *self);
93 bool cleanHandle(QSharedMemoryPrivate *self);
94 bool create(QSharedMemoryPrivate *self, qsizetype size);
95 bool attach(QSharedMemoryPrivate *self, QSharedMemory::AccessMode mode);
96 bool detach(QSharedMemoryPrivate *self);
101class QSharedMemorySystemV
104 static constexpr bool Enabled = QT_CONFIG(sysv_shm);
105 static bool supports(QNativeIpcKey::Type type)
106 {
return quint16(type) <= 0xff; }
107 static bool runtimeSupportCheck();
109#if QT_CONFIG(sysv_shm)
110 key_t handle(QSharedMemoryPrivate *self);
111 bool cleanHandle(QSharedMemoryPrivate *self);
112 bool create(QSharedMemoryPrivate *self, qsizetype size);
113 bool attach(QSharedMemoryPrivate *self, QSharedMemory::AccessMode mode);
114 bool detach(QSharedMemoryPrivate *self);
117 void updateNativeKeyFile(
const QNativeIpcKey &nativeKey);
119 QByteArray nativeKeyFile;
124class QSharedMemoryWin32
128 static constexpr bool Enabled =
true;
130 static constexpr bool Enabled =
false;
132 static bool runtimeSupportCheck() {
return Enabled; }
133 static bool supports(QNativeIpcKey::Type type)
134 {
return type == QNativeIpcKey::Type::Windows; }
136 Qt::HANDLE handle(QSharedMemoryPrivate *self);
137 bool cleanHandle(QSharedMemoryPrivate *self);
138 bool create(QSharedMemoryPrivate *self, qsizetype size);
139 bool attach(QSharedMemoryPrivate *self, QSharedMemory::AccessMode mode);
140 bool detach(QSharedMemoryPrivate *self);
142 Qt::HANDLE hand =
nullptr;
145class Q_AUTOTEST_EXPORT QSharedMemoryPrivate :
public QObjectPrivate
147 Q_DECLARE_PUBLIC(QSharedMemory)
150 QSharedMemoryPrivate(QNativeIpcKey::Type type) : nativeKey(type)
151 { constructBackend(); }
152 ~QSharedMemoryPrivate();
154 void *memory =
nullptr;
156 QNativeIpcKey nativeKey;
158#if QT_CONFIG(systemsemaphore)
159 using SemaphoreAccessMode = QSystemSemaphore::AccessMode;
160 QSystemSemaphore systemSemaphore{ QNativeIpcKey() };
161 bool lockedByMe =
false;
163 enum SemaphoreAccessMode {};
165 QSharedMemory::SharedMemoryError error = QSharedMemory::NoError;
170 QSharedMemoryPosix posix;
171 QSharedMemorySystemV sysv;
172 QSharedMemoryWin32 win32;
174 QtIpcCommon::IpcStorageVariant<&Backend::posix, &Backend::sysv, &Backend::win32> backend;
176 void constructBackend();
177 void destructBackend();
178 bool initKey(SemaphoreAccessMode mode);
180 template <
typename Lambda>
auto visit(
const Lambda &lambda)
182 return backend.visit(nativeKey.type(), lambda);
187 return visit([&](
auto p) {
return !!p->handle(
this); });
191 return visit([&](
auto p) {
return p->cleanHandle(
this); });
193 bool create(qsizetype sz)
195 return visit([&](
auto p) {
return p->create(
this, sz); });
197 bool attach(QSharedMemory::AccessMode mode)
199 return visit([&](
auto p) {
return p->attach(
this, mode); });
203 return visit([&](
auto p) {
return p->detach(
this); });
206 inline void setError(QSharedMemory::SharedMemoryError e,
const QString &message)
207 { error = e; errorString = message; }
208 void setUnixErrorString(QLatin1StringView function);
209 void setWindowsErrorString(QLatin1StringView function);
211#if QT_CONFIG(systemsemaphore)
212 bool tryLocker(QSharedMemoryLocker *locker,
const QString &function) {
213 if (!locker->lock()) {
214 errorString = QSharedMemory::tr(
"%1: unable to lock").arg(function);
215 error = QSharedMemory::LockError;
220 QNativeIpcKey semaphoreNativeKey()
const;