summaryrefslogtreecommitdiffstats
path: root/src/corelib/ipc/qtipccommon.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/ipc/qtipccommon.h')
-rw-r--r--src/corelib/ipc/qtipccommon.h206
1 files changed, 206 insertions, 0 deletions
diff --git a/src/corelib/ipc/qtipccommon.h b/src/corelib/ipc/qtipccommon.h
new file mode 100644
index 0000000000..74f30cb6a4
--- /dev/null
+++ b/src/corelib/ipc/qtipccommon.h
@@ -0,0 +1,206 @@
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QNATIVEIPCKEY_H
+#define QNATIVEIPCKEY_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qtcore-config.h>
+
+#if QT_CONFIG(sharedmemory) || QT_CONFIG(systemsemaphore)
+# include <QtCore/qstring.h>
+# include <QtCore/qobjectdefs.h>
+
+QT_BEGIN_NAMESPACE
+
+class QNativeIpcKeyPrivate;
+class QNativeIpcKey
+{
+ Q_GADGET_EXPORT(Q_CORE_EXPORT)
+public:
+ enum class Type : quint16 {
+ // 0 is reserved for the invalid type
+ // keep 1 through 0xff free, except for SystemV
+ SystemV = 0x51, // 'Q'
+
+ PosixRealtime = 0x100,
+ Windows,
+ };
+ Q_ENUM(Type)
+
+ static constexpr Type DefaultTypeForOs =
+#ifdef Q_OS_WIN
+ Type::Windows
+#else
+ Type::PosixRealtime
+#endif
+ ;
+ static Type legacyDefaultTypeForOs() noexcept;
+
+ constexpr QNativeIpcKey() noexcept = default;
+
+ explicit constexpr QNativeIpcKey(Type type) noexcept
+ : typeAndFlags{type}
+ {
+ }
+
+ Q_IMPLICIT QNativeIpcKey(const QString &k, Type type = DefaultTypeForOs)
+ : key(k), typeAndFlags{type}
+ {
+ }
+
+ QNativeIpcKey(const QNativeIpcKey &other)
+ : d(other.d), key(other.key), typeAndFlags(other.typeAndFlags)
+ {
+ if (isSlowPath())
+ copy_internal(other);
+ }
+
+ QNativeIpcKey(QNativeIpcKey &&other) noexcept
+ : d(std::exchange(other.d, nullptr)), key(std::move(other.key)),
+ typeAndFlags(std::move(other.typeAndFlags))
+ {
+ if (isSlowPath())
+ move_internal(std::move(other));
+ }
+
+ ~QNativeIpcKey()
+ {
+ if (isSlowPath())
+ destroy_internal();
+ }
+
+ QNativeIpcKey &operator=(const QNativeIpcKey &other)
+ {
+ typeAndFlags = other.typeAndFlags;
+ key = other.key;
+ if (isSlowPath() || other.isSlowPath())
+ return assign_internal(other);
+ Q_ASSERT(!d);
+ return *this;
+ }
+
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QNativeIpcKey)
+ void swap(QNativeIpcKey &other) noexcept
+ {
+ std::swap(d, other.d);
+ key.swap(other.key);
+ typeAndFlags.swap(other.typeAndFlags);
+ }
+
+ bool isEmpty() const noexcept
+ {
+ return key.isEmpty();
+ }
+
+ bool isValid() const noexcept
+ {
+ return type() != Type{};
+ }
+
+ constexpr Type type() const noexcept
+ {
+ return typeAndFlags.type;
+ }
+
+ constexpr void setType(Type type)
+ {
+ if (isSlowPath())
+ return setType_internal(type);
+ typeAndFlags.type = type;
+ }
+
+ QString nativeKey() const noexcept
+ {
+ return key;
+ }
+ void setNativeKey(const QString &newKey)
+ {
+ key = newKey;
+ if (isSlowPath())
+ setNativeKey_internal(newKey);
+ }
+
+ Q_CORE_EXPORT QString toString() const;
+ Q_CORE_EXPORT static QNativeIpcKey fromString(const QString &string);
+
+private:
+ struct TypeAndFlags {
+ Type type = DefaultTypeForOs;
+ quint16 reserved1 = {};
+ quint32 reserved2 = {};
+
+ void swap(TypeAndFlags &other) noexcept
+ {
+ std::swap(type, other.type);
+ std::swap(reserved1, other.reserved1);
+ std::swap(reserved2, other.reserved2);
+ }
+
+ friend constexpr bool operator==(const TypeAndFlags &lhs, const TypeAndFlags &rhs) noexcept
+ {
+ return lhs.type == rhs.type &&
+ lhs.reserved1 == rhs.reserved1 &&
+ lhs.reserved2 == rhs.reserved2;
+ }
+ };
+
+ QNativeIpcKeyPrivate *d = nullptr;
+ QString key;
+ TypeAndFlags typeAndFlags;
+
+ friend class QNativeIpcKeyPrivate;
+ constexpr bool isSlowPath() const noexcept
+ { return Q_UNLIKELY(d); }
+
+ friend Q_CORE_EXPORT size_t qHash(const QNativeIpcKey &ipcKey, size_t seed) noexcept;
+ friend size_t qHash(const QNativeIpcKey &ipcKey) noexcept
+ { return qHash(ipcKey, 0); }
+
+ Q_CORE_EXPORT void copy_internal(const QNativeIpcKey &other);
+ Q_CORE_EXPORT void move_internal(QNativeIpcKey &&other) noexcept;
+ Q_CORE_EXPORT QNativeIpcKey &assign_internal(const QNativeIpcKey &other);
+ Q_CORE_EXPORT void destroy_internal() noexcept;
+ Q_CORE_EXPORT void setType_internal(Type);
+ Q_CORE_EXPORT void setNativeKey_internal(const QString &);
+ Q_DECL_PURE_FUNCTION Q_CORE_EXPORT static int
+ compare_internal(const QNativeIpcKey &lhs, const QNativeIpcKey &rhs) noexcept;
+
+#ifdef Q_OS_DARWIN
+ Q_DECL_CONST_FUNCTION Q_CORE_EXPORT static Type defaultTypeForOs_internal() noexcept;
+#endif
+ friend bool comparesEqual(const QNativeIpcKey &lhs, const QNativeIpcKey &rhs) noexcept
+ {
+ if (!(lhs.typeAndFlags == rhs.typeAndFlags))
+ return false;
+ if (lhs.key != rhs.key)
+ return false;
+ if (lhs.d == rhs.d)
+ return true;
+ return compare_internal(lhs, rhs) == 0;
+ }
+ Q_DECLARE_EQUALITY_COMPARABLE(QNativeIpcKey)
+};
+
+// not a shared type, exactly, but this works too
+Q_DECLARE_SHARED(QNativeIpcKey)
+
+inline auto QNativeIpcKey::legacyDefaultTypeForOs() noexcept -> Type
+{
+#if defined(Q_OS_WIN)
+ return Type::Windows;
+#elif defined(QT_POSIX_IPC)
+ return Type::PosixRealtime;
+#elif defined(Q_OS_DARWIN)
+ return defaultTypeForOs_internal();
+#else
+ return Type::SystemV;
+#endif
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(sharedmemory) || QT_CONFIG(systemsemaphore)
+
+
+#endif // QNATIVEIPCKEY_H