Revision control
Copy as Markdown
// 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
// Qt-Security score:significant reason:default
#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 <sys/types.h>
#if QT_CONFIG(posix_sem)
# include <semaphore.h>
#endif
#ifndef SEM_FAILED
# define SEM_FAILED nullptr
struct sem_t;
#endif
#if QT_CONFIG(sysv_sem)
# include <sys/sem.h>
#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 <typename Lambda> 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