// Copyright (C) 2016 The Qt Company Ltd. // 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 QSYSTEMSEMAPHORE_P_H #define QSYSTEMSEMAPHORE_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 "qsystemsemaphore.h" #if QT_CONFIG(systemsemaphore) #include "qcoreapplication.h" #include "qtipccommon_p.h" #include "private/qtcore-config_p.h" #include #if QT_CONFIG(posix_sem) # include #endif #ifndef SEM_FAILED # define SEM_FAILED nullptr struct sem_t; #endif #if QT_CONFIG(sysv_sem) # include #endif QT_BEGIN_NAMESPACE class QSystemSemaphorePrivate; struct QSystemSemaphorePosix { static constexpr bool Enabled = QT_CONFIG(posix_sem); static bool supports(QNativeIpcKey::Type type) { return type == QNativeIpcKey::Type::PosixRealtime; } static bool runtimeSupportCheck(); bool handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode); void cleanHandle(QSystemSemaphorePrivate *self); bool modifySemaphore(QSystemSemaphorePrivate *self, int count); sem_t *semaphore = SEM_FAILED; bool createdSemaphore = false; }; struct QSystemSemaphoreSystemV { static constexpr bool Enabled = QT_CONFIG(sysv_sem); static bool supports(QNativeIpcKey::Type type) { return quint16(type) <= 0xff; } static bool runtimeSupportCheck(); #if QT_CONFIG(sysv_sem) key_t handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode); void cleanHandle(QSystemSemaphorePrivate *self); bool modifySemaphore(QSystemSemaphorePrivate *self, int count); QByteArray nativeKeyFile; key_t unix_key = -1; int semaphore = -1; bool createdFile = false; bool createdSemaphore = false; #endif }; struct QSystemSemaphoreWin32 { #ifdef Q_OS_WIN32 static constexpr bool Enabled = true; #else static constexpr bool Enabled = false; #endif static bool supports(QNativeIpcKey::Type type) { return type == QNativeIpcKey::Type::Windows; } static bool runtimeSupportCheck() { return Enabled; } // we can declare the members without the #if Qt::HANDLE handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode); void cleanHandle(QSystemSemaphorePrivate *self); bool modifySemaphore(QSystemSemaphorePrivate *self, int count); Qt::HANDLE semaphore = nullptr; }; class QSystemSemaphorePrivate { public: QSystemSemaphorePrivate(QNativeIpcKey::Type type) : nativeKey(type) { constructBackend(); } ~QSystemSemaphorePrivate() { destructBackend(); } void setWindowsErrorString(QLatin1StringView function); // Windows only void setUnixErrorString(QLatin1StringView function); inline void setError(QSystemSemaphore::SystemSemaphoreError e, const QString &message) { error = e; errorString = message; } inline void clearError() { setError(QSystemSemaphore::NoError, QString()); } QNativeIpcKey nativeKey; QString errorString; int initialValue; QSystemSemaphore::SystemSemaphoreError error = QSystemSemaphore::NoError; union Backend { Backend() {} ~Backend() {} QSystemSemaphorePosix posix; QSystemSemaphoreSystemV sysv; QSystemSemaphoreWin32 win32; }; QtIpcCommon::IpcStorageVariant<&Backend::posix, &Backend::sysv, &Backend::win32> backend; void constructBackend(); void destructBackend(); template auto visit(const Lambda &lambda) { return backend.visit(nativeKey.type(), lambda); } void handle(QSystemSemaphore::AccessMode mode) { visit([&](auto p) { p->handle(this, mode); }); } void cleanHandle() { visit([&](auto p) { p->cleanHandle(this); }); } bool modifySemaphore(int count) { return visit([&](auto p) { return p->modifySemaphore(this, count); }); } }; QT_END_NAMESPACE #endif // QT_CONFIG(systemsemaphore) #endif // QSYSTEMSEMAPHORE_P_H