summaryrefslogtreecommitdiffstats
path: root/src/corelib/ipc/qtipccommon_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/ipc/qtipccommon_p.h')
-rw-r--r--src/corelib/ipc/qtipccommon_p.h173
1 files changed, 173 insertions, 0 deletions
diff --git a/src/corelib/ipc/qtipccommon_p.h b/src/corelib/ipc/qtipccommon_p.h
new file mode 100644
index 0000000000..72762c5ba7
--- /dev/null
+++ b/src/corelib/ipc/qtipccommon_p.h
@@ -0,0 +1,173 @@
+// 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 QTIPCCOMMON_P_H
+#define QTIPCCOMMON_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qtipccommon.h"
+#include <private/qglobal_p.h>
+#include <private/qtcore-config_p.h>
+
+#if QT_CONFIG(sharedmemory) || QT_CONFIG(systemsemaphore)
+
+#if defined(Q_OS_UNIX)
+# include <qfile.h>
+# include <private/qcore_unix_p.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QNativeIpcKeyPrivate
+{
+public:
+ QString legacyKey_;
+
+ static QString legacyKey(const QNativeIpcKey &key)
+ {
+ if (key.isSlowPath())
+ return key.d->legacyKey_;
+ return QString();
+ }
+ static void setLegacyKey(QNativeIpcKey &key, const QString &legacyKey)
+ {
+ QNativeIpcKeyPrivate::makeExtended(key)->legacyKey_ = legacyKey;
+ }
+ static void setNativeAndLegacyKeys(QNativeIpcKey &key, const QString &nativeKey,
+ const QString &legacyKey)
+ {
+ key.setNativeKey(nativeKey);
+ setLegacyKey(key, legacyKey);
+ }
+
+private:
+ static QNativeIpcKeyPrivate *makeExtended(QNativeIpcKey &key)
+ {
+ if (!key.isSlowPath())
+ key.d = new QNativeIpcKeyPrivate;
+ return key.d;
+ }
+};
+
+namespace QtIpcCommon {
+enum class IpcType {
+ SharedMemory,
+ SystemSemaphore
+};
+
+static constexpr bool isIpcSupported(IpcType ipcType, QNativeIpcKey::Type type)
+{
+ switch (type) {
+ case QNativeIpcKey::Type::SystemV:
+ break;
+
+ case QNativeIpcKey::Type::PosixRealtime:
+ if (ipcType == IpcType::SharedMemory)
+ return QT_CONFIG(posix_shm);
+ return QT_CONFIG(posix_sem);
+
+ case QNativeIpcKey::Type::Windows:
+#ifdef Q_OS_WIN
+ return true;
+#else
+ return false;
+#endif
+ }
+
+ if (ipcType == IpcType::SharedMemory)
+ return QT_CONFIG(sysv_shm);
+ return QT_CONFIG(sysv_sem);
+}
+
+template <auto Member1, auto... Members> class IpcStorageVariant
+{
+ template <typename T, typename C> static C extractClass(T C::*);
+ template <typename T, typename C> static T extractObject(T C::*);
+
+ template <auto M>
+ static constexpr bool IsEnabled = decltype(extractObject(M))::Enabled;
+
+ static_assert(std::is_member_object_pointer_v<decltype(Member1)>);
+ using StorageType = decltype(extractClass(Member1));
+ StorageType d;
+
+public:
+ template <typename Lambda> static auto
+ visit_internal(StorageType &storage, QNativeIpcKey::Type keyType, const Lambda &lambda)
+ {
+ if constexpr ((IsEnabled<Member1> || ... || IsEnabled<Members>)) {
+ if constexpr (IsEnabled<Member1>) {
+ using MemberType1 = decltype(extractObject(Member1));
+ if (MemberType1::supports(keyType))
+ return lambda(&(storage.*Member1));
+ }
+ if constexpr ((... || IsEnabled<Members>))
+ return IpcStorageVariant<Members...>::visit_internal(storage, keyType, lambda);
+ Q_UNREACHABLE();
+ } else {
+ // no backends enabled, but we can't return void
+ return false;
+ }
+ }
+
+ template <typename Lambda> auto visit(QNativeIpcKey::Type keyType, const Lambda &lambda)
+ {
+ return visit_internal(d, keyType, lambda);
+ }
+
+ template <typename Lambda> static auto
+ staticVisit(QNativeIpcKey::Type keyType, const Lambda &lambda)
+ {
+ if constexpr ((IsEnabled<Member1> || ... || IsEnabled<Members>)) {
+ if constexpr (IsEnabled<Member1>) {
+ using MemberType1 = decltype(extractObject(Member1));
+ if (MemberType1::supports(keyType))
+ return lambda(static_cast<MemberType1 *>(nullptr));
+ }
+ if constexpr ((... || IsEnabled<Members>))
+ return IpcStorageVariant<Members...>::staticVisit(keyType, lambda);
+ Q_UNREACHABLE();
+ } else {
+ // no backends enabled, but we can't return void
+ return false;
+ }
+ }
+};
+
+QNativeIpcKey legacyPlatformSafeKey(const QString &key, IpcType ipcType, QNativeIpcKey::Type type);
+QNativeIpcKey platformSafeKey(const QString &key, IpcType ipcType, QNativeIpcKey::Type type);
+
+#ifdef Q_OS_UNIX
+// Convenience function to create the file if needed
+inline int createUnixKeyFile(const QByteArray &fileName)
+{
+ int fd = qt_safe_open(fileName.constData(), O_EXCL | O_CREAT | O_RDWR, 0640);
+ if (fd < 0) {
+ if (errno == EEXIST)
+ return 0;
+ return -1;
+ } else {
+ close(fd);
+ }
+ return 1;
+
+}
+#endif // Q_OS_UNIX
+} // namespace QtIpcCommon
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(sharedmemory) || QT_CONFIG(systemsemaphore)
+
+
+#endif // QTIPCCOMMON_P_H