IPC: add support for multiple backends to QSharedMemory
Simultaneously. Change-Id: If4c23ea3719947d790d4fffd17152760989b9bc6 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
32a06e9830
commit
0740ab56d7
@ -1135,9 +1135,12 @@ qt_internal_extend_target(Core CONDITION QT_FEATURE_clock_gettime AND UNIX
|
|||||||
WrapRt::WrapRt
|
WrapRt::WrapRt
|
||||||
)
|
)
|
||||||
|
|
||||||
qt_internal_extend_target(Core CONDITION UNIX
|
qt_internal_extend_target(Core CONDITION QT_FEATURE_posix_shm
|
||||||
SOURCES
|
SOURCES
|
||||||
ipc/qsharedmemory_posix.cpp
|
ipc/qsharedmemory_posix.cpp
|
||||||
|
)
|
||||||
|
qt_internal_extend_target(Core CONDITION QT_FEATURE_sysv_shm
|
||||||
|
SOURCES
|
||||||
ipc/qsharedmemory_systemv.cpp
|
ipc/qsharedmemory_systemv.cpp
|
||||||
)
|
)
|
||||||
qt_internal_extend_target(Core CONDITION QT_FEATURE_posix_sem
|
qt_internal_extend_target(Core CONDITION QT_FEATURE_posix_sem
|
||||||
|
@ -23,6 +23,30 @@ QT_BEGIN_NAMESPACE
|
|||||||
using namespace QtIpcCommon;
|
using namespace QtIpcCommon;
|
||||||
using namespace Qt::StringLiterals;
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
|
#if __cplusplus >= 202002L
|
||||||
|
using std::construct_at;
|
||||||
|
#else
|
||||||
|
template <typename T> static void construct_at(T *ptr)
|
||||||
|
{
|
||||||
|
new (ptr) T;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QSharedMemoryPrivate::~QSharedMemoryPrivate()
|
||||||
|
{
|
||||||
|
destructBackend();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void QSharedMemoryPrivate::constructBackend()
|
||||||
|
{
|
||||||
|
visit([](auto p) { construct_at(p); });
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void QSharedMemoryPrivate::destructBackend()
|
||||||
|
{
|
||||||
|
visit([](auto p) { std::destroy_at(p); });
|
||||||
|
}
|
||||||
|
|
||||||
#if QT_CONFIG(systemsemaphore)
|
#if QT_CONFIG(systemsemaphore)
|
||||||
inline QNativeIpcKey QSharedMemoryPrivate::semaphoreNativeKey() const
|
inline QNativeIpcKey QSharedMemoryPrivate::semaphoreNativeKey() const
|
||||||
{
|
{
|
||||||
@ -103,7 +127,7 @@ QSharedMemory::QSharedMemory(QObject *parent)
|
|||||||
\sa setNativeKey(), create(), attach()
|
\sa setNativeKey(), create(), attach()
|
||||||
*/
|
*/
|
||||||
QSharedMemory::QSharedMemory(const QNativeIpcKey &key, QObject *parent)
|
QSharedMemory::QSharedMemory(const QNativeIpcKey &key, QObject *parent)
|
||||||
: QObject(*new QSharedMemoryPrivate, parent)
|
: QObject(*new QSharedMemoryPrivate(key.type()), parent)
|
||||||
{
|
{
|
||||||
setNativeKey(key);
|
setNativeKey(key);
|
||||||
}
|
}
|
||||||
@ -120,12 +144,9 @@ QSharedMemory::QSharedMemory(const QNativeIpcKey &key, QObject *parent)
|
|||||||
\sa setKey(), create(), attach()
|
\sa setKey(), create(), attach()
|
||||||
*/
|
*/
|
||||||
QSharedMemory::QSharedMemory(const QString &key, QObject *parent)
|
QSharedMemory::QSharedMemory(const QString &key, QObject *parent)
|
||||||
: QObject(*new QSharedMemoryPrivate, parent)
|
: QSharedMemory(legacyNativeKey(key), parent)
|
||||||
{
|
{
|
||||||
QT_WARNING_PUSH
|
d_func()->legacyKey = key;
|
||||||
QT_WARNING_DISABLE_DEPRECATED
|
|
||||||
setKey(key);
|
|
||||||
QT_WARNING_POP
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -139,7 +160,10 @@ QSharedMemory::QSharedMemory(const QString &key, QObject *parent)
|
|||||||
*/
|
*/
|
||||||
QSharedMemory::~QSharedMemory()
|
QSharedMemory::~QSharedMemory()
|
||||||
{
|
{
|
||||||
setNativeKey(QNativeIpcKey());
|
Q_D(QSharedMemory);
|
||||||
|
if (isAttached())
|
||||||
|
detach();
|
||||||
|
d->cleanHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -224,7 +248,15 @@ void QSharedMemory::setNativeKey(const QNativeIpcKey &key)
|
|||||||
detach();
|
detach();
|
||||||
d->cleanHandle();
|
d->cleanHandle();
|
||||||
d->legacyKey = QString();
|
d->legacyKey = QString();
|
||||||
|
if (key.type() == d->nativeKey.type()) {
|
||||||
|
// we can reuse the backend
|
||||||
d->nativeKey = key;
|
d->nativeKey = key;
|
||||||
|
} else {
|
||||||
|
// we must recreate the backend
|
||||||
|
d->destructBackend();
|
||||||
|
d->nativeKey = key;
|
||||||
|
d->constructBackend();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QSharedMemoryPrivate::initKey(SemaphoreAccessMode mode)
|
bool QSharedMemoryPrivate::initKey(SemaphoreAccessMode mode)
|
||||||
@ -642,7 +674,13 @@ void QSharedMemoryPrivate::setUnixErrorString(QLatin1StringView function)
|
|||||||
|
|
||||||
bool QSharedMemory::isKeyTypeSupported(QNativeIpcKey::Type type)
|
bool QSharedMemory::isKeyTypeSupported(QNativeIpcKey::Type type)
|
||||||
{
|
{
|
||||||
return QSharedMemoryPrivate::DefaultBackend::supports(type);
|
if (!isIpcSupported(IpcType::SharedMemory, type))
|
||||||
|
return false;
|
||||||
|
using Variant = decltype(QSharedMemoryPrivate::backend);
|
||||||
|
return Variant::staticVisit(type, [](auto ptr) {
|
||||||
|
using Impl = std::decay_t<decltype(*ptr)>;
|
||||||
|
return Impl::runtimeSupportCheck();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
QNativeIpcKey QSharedMemory::platformSafeKey(const QString &key, QNativeIpcKey::Type type)
|
QNativeIpcKey QSharedMemory::platformSafeKey(const QString &key, QNativeIpcKey::Type type)
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#if QT_CONFIG(sharedmemory)
|
#if QT_CONFIG(sharedmemory)
|
||||||
#include "qsystemsemaphore.h"
|
#include "qsystemsemaphore.h"
|
||||||
|
#include "qtipccommon_p.h"
|
||||||
#include "private/qobject_p.h"
|
#include "private/qobject_p.h"
|
||||||
|
|
||||||
#if QT_CONFIG(posix_shm)
|
#if QT_CONFIG(posix_shm)
|
||||||
@ -69,8 +70,10 @@ private:
|
|||||||
class QSharedMemoryPosix
|
class QSharedMemoryPosix
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static constexpr bool Enabled = QT_CONFIG(posix_shm);
|
||||||
static bool supports(QNativeIpcKey::Type type)
|
static bool supports(QNativeIpcKey::Type type)
|
||||||
{ return type == QNativeIpcKey::Type::PosixRealtime; }
|
{ return type == QNativeIpcKey::Type::PosixRealtime; }
|
||||||
|
static bool runtimeSupportCheck();
|
||||||
|
|
||||||
bool handle(QSharedMemoryPrivate *self);
|
bool handle(QSharedMemoryPrivate *self);
|
||||||
bool cleanHandle(QSharedMemoryPrivate *self);
|
bool cleanHandle(QSharedMemoryPrivate *self);
|
||||||
@ -84,8 +87,10 @@ public:
|
|||||||
class QSharedMemorySystemV
|
class QSharedMemorySystemV
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static constexpr bool Enabled = QT_CONFIG(sysv_shm);
|
||||||
static bool supports(QNativeIpcKey::Type type)
|
static bool supports(QNativeIpcKey::Type type)
|
||||||
{ return quint16(type) <= 0xff; }
|
{ return quint16(type) <= 0xff; }
|
||||||
|
static bool runtimeSupportCheck();
|
||||||
|
|
||||||
#if QT_CONFIG(sysv_sem)
|
#if QT_CONFIG(sysv_sem)
|
||||||
key_t handle(QSharedMemoryPrivate *self);
|
key_t handle(QSharedMemoryPrivate *self);
|
||||||
@ -105,6 +110,12 @@ private:
|
|||||||
class QSharedMemoryWin32
|
class QSharedMemoryWin32
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
static constexpr bool Enabled = true;
|
||||||
|
#else
|
||||||
|
static constexpr bool Enabled = false;
|
||||||
|
#endif
|
||||||
|
static bool runtimeSupportCheck() { return Enabled; }
|
||||||
static bool supports(QNativeIpcKey::Type type)
|
static bool supports(QNativeIpcKey::Type type)
|
||||||
{ return type == QNativeIpcKey::Type::Windows; }
|
{ return type == QNativeIpcKey::Type::Windows; }
|
||||||
|
|
||||||
@ -122,6 +133,10 @@ class Q_AUTOTEST_EXPORT QSharedMemoryPrivate : public QObjectPrivate
|
|||||||
Q_DECLARE_PUBLIC(QSharedMemory)
|
Q_DECLARE_PUBLIC(QSharedMemory)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
QSharedMemoryPrivate(QNativeIpcKey::Type type) : nativeKey(type)
|
||||||
|
{ constructBackend(); }
|
||||||
|
~QSharedMemoryPrivate();
|
||||||
|
|
||||||
void *memory = nullptr;
|
void *memory = nullptr;
|
||||||
qsizetype size = 0;
|
qsizetype size = 0;
|
||||||
QNativeIpcKey nativeKey;
|
QNativeIpcKey nativeKey;
|
||||||
@ -135,36 +150,43 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
QSharedMemory::SharedMemoryError error = QSharedMemory::NoError;
|
QSharedMemory::SharedMemoryError error = QSharedMemory::NoError;
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
union Backend {
|
||||||
using DefaultBackend = QSharedMemoryWin32;
|
Backend() {}
|
||||||
#elif defined(QT_POSIX_IPC)
|
~Backend() {}
|
||||||
using DefaultBackend = QSharedMemoryPosix;
|
QSharedMemoryPosix posix;
|
||||||
#else
|
QSharedMemorySystemV sysv;
|
||||||
using DefaultBackend = QSharedMemorySystemV;
|
QSharedMemoryWin32 win32;
|
||||||
#endif
|
};
|
||||||
DefaultBackend backend;
|
QtIpcCommon::IpcStorageVariant<&Backend::posix, &Backend::sysv, &Backend::win32> backend;
|
||||||
|
|
||||||
|
void constructBackend();
|
||||||
|
void destructBackend();
|
||||||
bool initKey(SemaphoreAccessMode mode);
|
bool initKey(SemaphoreAccessMode mode);
|
||||||
|
|
||||||
|
template <typename Lambda> auto visit(const Lambda &lambda)
|
||||||
|
{
|
||||||
|
return backend.visit(nativeKey.type(), lambda);
|
||||||
|
}
|
||||||
|
|
||||||
bool handle()
|
bool handle()
|
||||||
{
|
{
|
||||||
return backend.handle(this);
|
return visit([=](auto p) { return !!p->handle(this); });
|
||||||
}
|
}
|
||||||
bool cleanHandle()
|
bool cleanHandle()
|
||||||
{
|
{
|
||||||
return backend.cleanHandle(this);
|
return visit([=](auto p) { return p->cleanHandle(this); });
|
||||||
}
|
}
|
||||||
bool create(qsizetype size)
|
bool create(qsizetype size)
|
||||||
{
|
{
|
||||||
return backend.create(this, size);
|
return visit([=](auto p) { return p->create(this, size); });
|
||||||
}
|
}
|
||||||
bool attach(QSharedMemory::AccessMode mode)
|
bool attach(QSharedMemory::AccessMode mode)
|
||||||
{
|
{
|
||||||
return backend.attach(this, mode);
|
return visit([=](auto p) { return p->attach(this, mode); });
|
||||||
}
|
}
|
||||||
bool detach()
|
bool detach()
|
||||||
{
|
{
|
||||||
return backend.detach(this);
|
return visit([=](auto p) { return p->detach(this); });
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setError(QSharedMemory::SharedMemoryError e, const QString &message)
|
inline void setError(QSharedMemory::SharedMemoryError e, const QString &message)
|
||||||
|
@ -24,6 +24,15 @@ QT_BEGIN_NAMESPACE
|
|||||||
using namespace Qt::StringLiterals;
|
using namespace Qt::StringLiterals;
|
||||||
using namespace QtIpcCommon;
|
using namespace QtIpcCommon;
|
||||||
|
|
||||||
|
bool QSharedMemoryPosix::runtimeSupportCheck()
|
||||||
|
{
|
||||||
|
static const bool result = []() {
|
||||||
|
shm_open("", 0, 0); // this WILL fail
|
||||||
|
return errno != ENOSYS;
|
||||||
|
}();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool QSharedMemoryPosix::handle(QSharedMemoryPrivate *self)
|
bool QSharedMemoryPosix::handle(QSharedMemoryPrivate *self)
|
||||||
{
|
{
|
||||||
// don't allow making handles on empty keys
|
// don't allow making handles on empty keys
|
||||||
|
@ -20,12 +20,29 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "private/qcore_unix_p.h"
|
#include "private/qcore_unix_p.h"
|
||||||
|
#if defined(Q_OS_DARWIN)
|
||||||
|
#include "private/qcore_mac_p.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
using namespace Qt::StringLiterals;
|
using namespace Qt::StringLiterals;
|
||||||
using namespace QtIpcCommon;
|
using namespace QtIpcCommon;
|
||||||
|
|
||||||
|
bool QSharedMemorySystemV::runtimeSupportCheck()
|
||||||
|
{
|
||||||
|
#if defined(Q_OS_DARWIN)
|
||||||
|
if (qt_apple_isSandboxed())
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
static const bool result = []() {
|
||||||
|
shmget(IPC_PRIVATE, ~size_t(0), 0); // this will fail
|
||||||
|
return errno != ENOSYS;
|
||||||
|
}();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void QSharedMemorySystemV::updateNativeKeyFile(const QNativeIpcKey &nativeKey)
|
inline void QSharedMemorySystemV::updateNativeKeyFile(const QNativeIpcKey &nativeKey)
|
||||||
{
|
{
|
||||||
Q_ASSERT(nativeKeyFile.isEmpty() );
|
Q_ASSERT(nativeKeyFile.isEmpty() );
|
||||||
|
@ -85,33 +85,6 @@ static QNativeIpcKey::Type stringToType(QStringView typeString)
|
|||||||
return QNativeIpcKey::Type{};
|
return QNativeIpcKey::Type{};
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(Q_OS_DARWIN) || defined(QT_BUILD_INTERNAL)
|
|
||||||
/*!
|
|
||||||
\internal
|
|
||||||
|
|
||||||
Returns whether this IPC type \a ipcType and key type \a keyType is
|
|
||||||
supported on the current machine, with a runtime check.
|
|
||||||
*/
|
|
||||||
bool QtIpcCommon::isIpcSupportedAtRuntime(IpcType ipcType, QNativeIpcKey::Type keyType)
|
|
||||||
{
|
|
||||||
switch (keyType) {
|
|
||||||
case QNativeIpcKey::Type::SystemV:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QNativeIpcKey::Type::PosixRealtime:
|
|
||||||
case QNativeIpcKey::Type::Windows:
|
|
||||||
return isIpcSupported(ipcType, keyType);
|
|
||||||
}
|
|
||||||
|
|
||||||
# if defined(Q_OS_DARWIN)
|
|
||||||
// System V IPC is not supported on Apple platforms if the application is
|
|
||||||
// currently running in a sandbox.
|
|
||||||
return !qt_apple_isSandboxed();
|
|
||||||
# endif
|
|
||||||
return isIpcSupported(ipcType, keyType);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
|
|
||||||
|
@ -57,11 +57,6 @@ static constexpr bool isIpcSupported(IpcType ipcType, QNativeIpcKey::Type type)
|
|||||||
return QT_CONFIG(sysv_shm);
|
return QT_CONFIG(sysv_shm);
|
||||||
return QT_CONFIG(sysv_sem);
|
return QT_CONFIG(sysv_sem);
|
||||||
}
|
}
|
||||||
#if defined(Q_OS_DARWIN) || defined(QT_BUILD_INTERNAL)
|
|
||||||
bool isIpcSupportedAtRuntime(IpcType type, QNativeIpcKey::Type);
|
|
||||||
#else
|
|
||||||
static constexpr auto isIpcSupportedAtRuntime = isIpcSupported;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <auto Member1, auto... Members> class IpcStorageVariant
|
template <auto Member1, auto... Members> class IpcStorageVariant
|
||||||
{
|
{
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "private/qtcore-config_p.h"
|
#include "private/qtcore-config_p.h"
|
||||||
|
#include "../ipctestcommon.h"
|
||||||
|
|
||||||
#define EXISTING_SIZE 1024
|
#define EXISTING_SIZE 1024
|
||||||
|
|
||||||
@ -31,15 +32,11 @@ class tst_QSharedMemory : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
|
||||||
tst_QSharedMemory();
|
|
||||||
virtual ~tst_QSharedMemory();
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
|
void initTestCase();
|
||||||
void init();
|
void init();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
// basics
|
// basics
|
||||||
void constructor();
|
void constructor();
|
||||||
@ -51,6 +48,8 @@ private slots:
|
|||||||
void create();
|
void create();
|
||||||
void attach_data();
|
void attach_data();
|
||||||
void attach();
|
void attach();
|
||||||
|
void changeKeyType_data() { attach_data(); }
|
||||||
|
void changeKeyType();
|
||||||
void lock();
|
void lock();
|
||||||
|
|
||||||
// custom edge cases
|
// custom edge cases
|
||||||
@ -92,7 +91,7 @@ protected:
|
|||||||
|
|
||||||
QNativeIpcKey platformSafeKey(const QString &key)
|
QNativeIpcKey platformSafeKey(const QString &key)
|
||||||
{
|
{
|
||||||
QNativeIpcKey::Type keyType = QNativeIpcKey::DefaultTypeForOs;
|
QFETCH_GLOBAL(QNativeIpcKey::Type, keyType);
|
||||||
return QSharedMemory::platformSafeKey(mangleKey(key), keyType);
|
return QSharedMemory::platformSafeKey(mangleKey(key), keyType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,21 +107,16 @@ protected:
|
|||||||
|
|
||||||
QList<QNativeIpcKey> keys;
|
QList<QNativeIpcKey> keys;
|
||||||
QList<QSharedMemory*> jail;
|
QList<QSharedMemory*> jail;
|
||||||
QSharedMemory *existingSharedMemory;
|
QSharedMemory *existingSharedMemory = nullptr;
|
||||||
int seq = 0;
|
int seq = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QString m_helperBinary;
|
const QString m_helperBinary = "./producerconsumer_helper";
|
||||||
};
|
};
|
||||||
|
|
||||||
tst_QSharedMemory::tst_QSharedMemory()
|
void tst_QSharedMemory::initTestCase()
|
||||||
: existingSharedMemory(0)
|
|
||||||
, m_helperBinary("./producerconsumer_helper")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
tst_QSharedMemory::~tst_QSharedMemory()
|
|
||||||
{
|
{
|
||||||
|
IpcTestCommon::addGlobalTestRows<QSharedMemory>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QSharedMemory::init()
|
void tst_QSharedMemory::init()
|
||||||
@ -285,6 +279,25 @@ void tst_QSharedMemory::nativeKey()
|
|||||||
QCOMPARE(sm.size(), 0);
|
QCOMPARE(sm.size(), 0);
|
||||||
|
|
||||||
QCOMPARE(sm.detach(), false);
|
QCOMPARE(sm.detach(), false);
|
||||||
|
|
||||||
|
// change the key type
|
||||||
|
QNativeIpcKey::Type nextKeyType = IpcTestCommon::nextKeyType(setIpcKey.type());
|
||||||
|
if (nextKeyType != setIpcKey.type()) {
|
||||||
|
QNativeIpcKey setIpcKey2 = QSharedMemory::platformSafeKey(setKey, nextKeyType);
|
||||||
|
sm.setNativeKey(setIpcKey2);
|
||||||
|
|
||||||
|
QCOMPARE(sm.nativeIpcKey(), setIpcKey2);
|
||||||
|
QCOMPARE(sm.nativeKey(), setIpcKey2.nativeKey());
|
||||||
|
|
||||||
|
QCOMPARE(sm.isAttached(), false);
|
||||||
|
|
||||||
|
QCOMPARE(sm.error(), QSharedMemory::NoError);
|
||||||
|
QCOMPARE(sm.errorString(), QString());
|
||||||
|
QVERIFY(!sm.data());
|
||||||
|
QCOMPARE(sm.size(), 0);
|
||||||
|
|
||||||
|
QCOMPARE(sm.detach(), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_WARNING_PUSH
|
QT_WARNING_PUSH
|
||||||
@ -408,6 +421,34 @@ void tst_QSharedMemory::attach()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QSharedMemory::changeKeyType()
|
||||||
|
{
|
||||||
|
QFETCH(QString, key);
|
||||||
|
QFETCH(bool, exists);
|
||||||
|
QFETCH(QSharedMemory::SharedMemoryError, error);
|
||||||
|
|
||||||
|
QNativeIpcKey nativeKey = platformSafeKey(key);
|
||||||
|
QNativeIpcKey::Type nextKeyType = IpcTestCommon::nextKeyType(nativeKey.type());
|
||||||
|
if (nextKeyType == nativeKey.type())
|
||||||
|
QSKIP("System only supports one key type");
|
||||||
|
// qDebug() << "Changing from" << nativeKey.type() << "to" << nextKeyType;
|
||||||
|
|
||||||
|
QSharedMemory sm(nativeKey);
|
||||||
|
QCOMPARE(sm.attach(), exists);
|
||||||
|
QCOMPARE(sm.error(), error);
|
||||||
|
|
||||||
|
QNativeIpcKey nextKey =
|
||||||
|
QSharedMemory::platformSafeKey(mangleKey(key), nextKeyType);
|
||||||
|
sm.setNativeKey(nextKey);
|
||||||
|
QCOMPARE(sm.isAttached(), false);
|
||||||
|
QVERIFY(!sm.attach());
|
||||||
|
|
||||||
|
if (exists)
|
||||||
|
QCOMPARE(sm.error(), QSharedMemory::NotFound);
|
||||||
|
else
|
||||||
|
QCOMPARE(sm.error(), error);
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QSharedMemory::lock()
|
void tst_QSharedMemory::lock()
|
||||||
{
|
{
|
||||||
QSharedMemory shm;
|
QSharedMemory shm;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user