IPC: split the backend implementations of QSystemSemaphore...
Into separate classes. This temporarily compiles QSystemSemaphorePosix on most Unix systems despite defaulting to SystemV. Change-Id: I12a088d1ae424825abd3fffd171d23191fbb6db3 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>bb10
parent
8b92d5a122
commit
75e73ea7fc
|
|
@ -1142,6 +1142,9 @@ qt_internal_extend_target(Core CONDITION UNIX AND NOT ANDROID
|
|||
ipc/qsharedmemory_posix.cpp
|
||||
ipc/qsharedmemory_systemv.cpp
|
||||
ipc/qsharedmemory_unix.cpp
|
||||
)
|
||||
qt_internal_extend_target(Core CONDITION UNIX
|
||||
SOURCES
|
||||
ipc/qsystemsemaphore_posix.cpp
|
||||
ipc/qsystemsemaphore_systemv.cpp
|
||||
ipc/qsystemsemaphore_unix.cpp
|
||||
|
|
|
|||
|
|
@ -758,7 +758,7 @@ qt_feature("systemsemaphore" PUBLIC
|
|||
SECTION "Kernel"
|
||||
LABEL "QSystemSemaphore"
|
||||
PURPOSE "Provides a general counting system semaphore."
|
||||
CONDITION ( NOT INTEGRITY AND NOT VXWORKS AND NOT rtems ) AND ( ANDROID OR WIN32 OR TEST_sysv_sem OR TEST_posix_sem )
|
||||
CONDITION WIN32 OR TEST_sysv_sem OR TEST_posix_sem
|
||||
)
|
||||
qt_feature_definition("systemsemaphore" "QT_NO_SYSTEMSEMAPHORE" NEGATE VALUE "1")
|
||||
qt_feature("xmlstream" PUBLIC
|
||||
|
|
|
|||
|
|
@ -201,9 +201,9 @@ void QSystemSemaphore::setKey(const QString &key, int initialValue, AccessMode m
|
|||
d->clearError();
|
||||
#if !defined(Q_OS_WIN) && !defined(QT_POSIX_IPC)
|
||||
// optimization to not destroy/create the file & semaphore
|
||||
if (key == d->key && mode == Create && d->createdSemaphore && d->createdFile) {
|
||||
if (key == d->key && mode == Create && d->backend.createdSemaphore && d->backend.createdFile) {
|
||||
d->initialValue = initialValue;
|
||||
d->unix_key = -1;
|
||||
d->backend.unix_key = -1;
|
||||
d->handle(mode);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright (C) 2012 Collabora Ltd, author <robin.burchell@collabora.co.uk>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#include "qsystemsemaphore.h"
|
||||
#include "qsystemsemaphore_p.h"
|
||||
|
||||
#include <qdebug.h>
|
||||
|
||||
#if QT_CONFIG(systemsemaphore)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
void QSystemSemaphorePrivate::setErrorString(const QString &function)
|
||||
{
|
||||
Q_UNUSED(function);
|
||||
Q_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
|
||||
{
|
||||
Q_UNUSED(mode);
|
||||
Q_UNIMPLEMENTED();
|
||||
return -1;
|
||||
}
|
||||
|
||||
void QSystemSemaphorePrivate::cleanHandle()
|
||||
{
|
||||
Q_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
bool QSystemSemaphorePrivate::modifySemaphore(int count)
|
||||
{
|
||||
Q_UNUSED(count);
|
||||
Q_UNIMPLEMENTED();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_CONFIG(systemsemaphore)
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
// 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
|
||||
|
|
@ -21,58 +22,100 @@
|
|||
|
||||
#include "qcoreapplication.h"
|
||||
#include "qtipccommon_p.h"
|
||||
#include "private/qtcore-config_p.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef QT_POSIX_IPC
|
||||
# include <semaphore.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
|
||||
class QSystemSemaphorePrivate;
|
||||
|
||||
struct QSystemSemaphorePosix
|
||||
{
|
||||
bool handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode);
|
||||
void cleanHandle(QSystemSemaphorePrivate *self);
|
||||
bool modifySemaphore(QSystemSemaphorePrivate *self, int count);
|
||||
|
||||
public:
|
||||
|
||||
QString makeKeyFileName()
|
||||
{
|
||||
return QtIpcCommon::legacyPlatformSafeKey(key, QtIpcCommon::IpcType::SystemSemaphore);
|
||||
}
|
||||
|
||||
inline void setError(QSystemSemaphore::SystemSemaphoreError e, const QString &message)
|
||||
{ error = e; errorString = message; }
|
||||
inline void clearError()
|
||||
{ setError(QSystemSemaphore::NoError, QString()); }
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
Qt::HANDLE handle(QSystemSemaphore::AccessMode mode = QSystemSemaphore::Open);
|
||||
void setErrorString(const QString &function);
|
||||
#elif defined(QT_POSIX_IPC)
|
||||
bool handle(QSystemSemaphore::AccessMode mode = QSystemSemaphore::Open);
|
||||
void setErrorString(const QString &function);
|
||||
#else
|
||||
key_t handle(QSystemSemaphore::AccessMode mode = QSystemSemaphore::Open);
|
||||
void setErrorString(const QString &function);
|
||||
#endif
|
||||
void cleanHandle();
|
||||
bool modifySemaphore(int count);
|
||||
|
||||
QString key;
|
||||
QString fileName;
|
||||
int initialValue;
|
||||
#ifdef Q_OS_WIN
|
||||
Qt::HANDLE semaphore = nullptr;
|
||||
#elif defined(QT_POSIX_IPC)
|
||||
sem_t *semaphore = SEM_FAILED;
|
||||
bool createdSemaphore = false;
|
||||
#else
|
||||
};
|
||||
|
||||
struct QSystemSemaphoreSystemV
|
||||
{
|
||||
#if QT_CONFIG(sysv_sem)
|
||||
key_t handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode);
|
||||
void cleanHandle(QSystemSemaphorePrivate *self);
|
||||
bool modifySemaphore(QSystemSemaphorePrivate *self, int count);
|
||||
|
||||
key_t unix_key = -1;
|
||||
int semaphore = -1;
|
||||
bool createdFile = false;
|
||||
bool createdSemaphore = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct QSystemSemaphoreWin32
|
||||
{
|
||||
//#ifdef Q_OS_WIN32 but there's nothing Windows-specific in the header
|
||||
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:
|
||||
QString makeKeyFileName()
|
||||
{
|
||||
return QtIpcCommon::legacyPlatformSafeKey(key, QtIpcCommon::IpcType::SystemSemaphore);
|
||||
}
|
||||
|
||||
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()); }
|
||||
|
||||
QString key;
|
||||
QString fileName;
|
||||
QString errorString;
|
||||
int initialValue;
|
||||
QSystemSemaphore::SystemSemaphoreError error = QSystemSemaphore::NoError;
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
using DefaultBackend = QSystemSemaphoreWin32;
|
||||
#elif defined(QT_POSIX_IPC)
|
||||
using DefaultBackend = QSystemSemaphorePosix;
|
||||
#else
|
||||
using DefaultBackend = QSystemSemaphoreSystemV;
|
||||
#endif
|
||||
DefaultBackend backend;
|
||||
|
||||
void handle(QSystemSemaphore::AccessMode mode)
|
||||
{
|
||||
backend.handle(this, mode);
|
||||
}
|
||||
void cleanHandle()
|
||||
{
|
||||
backend.cleanHandle(this);
|
||||
}
|
||||
bool modifySemaphore(int count)
|
||||
{
|
||||
return backend.modifySemaphore(this, count);
|
||||
}
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (C) 2015 Konstantin Ritt <ritt.ks@gmail.com>
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Tobias Koenig <tobias.koenig@kdab.com>
|
||||
// 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
|
||||
|
||||
#include "qsystemsemaphore.h"
|
||||
|
|
@ -10,9 +11,7 @@
|
|||
#include <qfile.h>
|
||||
#include <qcoreapplication.h>
|
||||
|
||||
#ifdef QT_POSIX_IPC
|
||||
|
||||
#if QT_CONFIG(systemsemaphore)
|
||||
#if QT_CONFIG(posix_sem)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
|
|
@ -30,29 +29,30 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
bool QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
|
||||
bool QSystemSemaphorePosix::handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode)
|
||||
{
|
||||
if (semaphore != SEM_FAILED)
|
||||
return true; // we already have a semaphore
|
||||
|
||||
if (fileName.isEmpty()) {
|
||||
errorString = QSystemSemaphore::tr("%1: key is empty").arg("QSystemSemaphore::handle"_L1);
|
||||
error = QSystemSemaphore::KeyError;
|
||||
if (self->fileName.isEmpty()) {
|
||||
self->setError(QSystemSemaphore::KeyError,
|
||||
QSystemSemaphore::tr("%1: key is empty")
|
||||
.arg("QSystemSemaphore::handle"_L1));
|
||||
return false;
|
||||
}
|
||||
|
||||
const QByteArray semName = QFile::encodeName(fileName);
|
||||
const QByteArray semName = QFile::encodeName(self->fileName);
|
||||
|
||||
// Always try with O_EXCL so we know whether we created the semaphore.
|
||||
int oflag = O_CREAT | O_EXCL;
|
||||
for (int tryNum = 0, maxTries = 1; tryNum < maxTries; ++tryNum) {
|
||||
do {
|
||||
semaphore = ::sem_open(semName.constData(), oflag, 0600, initialValue);
|
||||
semaphore = ::sem_open(semName.constData(), oflag, 0600, self->initialValue);
|
||||
} while (semaphore == SEM_FAILED && errno == EINTR);
|
||||
if (semaphore == SEM_FAILED && errno == EEXIST) {
|
||||
if (mode == QSystemSemaphore::Create) {
|
||||
if (::sem_unlink(semName.constData()) == -1 && errno != ENOENT) {
|
||||
setErrorString("QSystemSemaphore::handle (sem_unlink)"_L1);
|
||||
self->setUnixErrorString("QSystemSemaphore::handle (sem_unlink)"_L1);
|
||||
return false;
|
||||
}
|
||||
// Race condition: the semaphore might be recreated before
|
||||
|
|
@ -70,7 +70,7 @@ bool QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
|
|||
}
|
||||
|
||||
if (semaphore == SEM_FAILED) {
|
||||
setErrorString("QSystemSemaphore::handle"_L1);
|
||||
self->setUnixErrorString("QSystemSemaphore::handle"_L1);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -79,11 +79,11 @@ bool QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
|
|||
return true;
|
||||
}
|
||||
|
||||
void QSystemSemaphorePrivate::cleanHandle()
|
||||
void QSystemSemaphorePosix::cleanHandle(QSystemSemaphorePrivate *self)
|
||||
{
|
||||
if (semaphore != SEM_FAILED) {
|
||||
if (::sem_close(semaphore) == -1) {
|
||||
setErrorString("QSystemSemaphore::cleanHandle (sem_close)"_L1);
|
||||
self->setUnixErrorString("QSystemSemaphore::cleanHandle (sem_close)"_L1);
|
||||
#if defined QSYSTEMSEMAPHORE_DEBUG
|
||||
qDebug("QSystemSemaphore::cleanHandle sem_close failed.");
|
||||
#endif
|
||||
|
|
@ -92,28 +92,29 @@ void QSystemSemaphorePrivate::cleanHandle()
|
|||
}
|
||||
|
||||
if (createdSemaphore) {
|
||||
if (::sem_unlink(QFile::encodeName(fileName).constData()) == -1 && errno != ENOENT) {
|
||||
setErrorString("QSystemSemaphore::cleanHandle (sem_unlink)"_L1);
|
||||
if (::sem_unlink(QFile::encodeName(self->fileName).constData()) == -1
|
||||
&& errno != ENOENT) {
|
||||
self->setUnixErrorString("QSystemSemaphore::cleanHandle (sem_unlink)"_L1);
|
||||
#if defined QSYSTEMSEMAPHORE_DEBUG
|
||||
qDebug("QSystemSemaphore::cleanHandle sem_unlink failed.");
|
||||
qDebug("QSystemSemaphorePosix::cleanHandle sem_unlink failed.");
|
||||
#endif
|
||||
}
|
||||
createdSemaphore = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool QSystemSemaphorePrivate::modifySemaphore(int count)
|
||||
bool QSystemSemaphorePosix::modifySemaphore(QSystemSemaphorePrivate *self, int count)
|
||||
{
|
||||
if (!handle())
|
||||
if (!handle(self, QSystemSemaphore::Open))
|
||||
return false;
|
||||
|
||||
if (count > 0) {
|
||||
int cnt = count;
|
||||
do {
|
||||
if (::sem_post(semaphore) == -1) {
|
||||
setErrorString("QSystemSemaphore::modifySemaphore (sem_post)"_L1);
|
||||
self->setUnixErrorString("QSystemSemaphore::modifySemaphore (sem_post)"_L1);
|
||||
#if defined QSYSTEMSEMAPHORE_DEBUG
|
||||
qDebug("QSystemSemaphore::modify sem_post failed %d %d", count, errno);
|
||||
qDebug("QSystemSemaphorePosix::modify sem_post failed %d %d", count, errno);
|
||||
#endif
|
||||
// rollback changes to preserve the SysV semaphore behavior
|
||||
for ( ; cnt < count; ++cnt) {
|
||||
|
|
@ -131,22 +132,20 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count)
|
|||
// If the semaphore was removed be nice and create it and then modifySemaphore again
|
||||
if (errno == EINVAL || errno == EIDRM) {
|
||||
semaphore = SEM_FAILED;
|
||||
return modifySemaphore(count);
|
||||
return modifySemaphore(self, count);
|
||||
}
|
||||
setErrorString("QSystemSemaphore::modifySemaphore (sem_wait)"_L1);
|
||||
self->setUnixErrorString("QSystemSemaphore::modifySemaphore (sem_wait)"_L1);
|
||||
#if defined QSYSTEMSEMAPHORE_DEBUG
|
||||
qDebug("QSystemSemaphore::modify sem_wait failed %d %d", count, errno);
|
||||
qDebug("QSystemSemaphorePosix::modify sem_wait failed %d %d", count, errno);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
clearError();
|
||||
self->clearError();
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_CONFIG(systemsemaphore)
|
||||
|
||||
#endif // QT_POSIX_IPC
|
||||
#endif // QT_CONFIG(posix_sem)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// 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
|
||||
|
||||
#include "qsystemsemaphore.h"
|
||||
|
|
@ -8,9 +9,7 @@
|
|||
#include <qfile.h>
|
||||
#include <qcoreapplication.h>
|
||||
|
||||
#ifndef QT_POSIX_IPC
|
||||
|
||||
#if QT_CONFIG(systemsemaphore)
|
||||
#if QT_CONFIG(sysv_sem)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
|
|
@ -39,22 +38,24 @@ using namespace Qt::StringLiterals;
|
|||
|
||||
Setup unix_key
|
||||
*/
|
||||
key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
|
||||
key_t QSystemSemaphoreSystemV::handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode)
|
||||
{
|
||||
#if defined(Q_OS_DARWIN)
|
||||
if (qt_apple_isSandboxed()) {
|
||||
errorString = QSystemSemaphore::tr("%1: System V semaphores are not available " \
|
||||
"for sandboxed applications. Please build Qt with -feature-ipc_posix")
|
||||
.arg("QSystemSemaphore::handle:"_L1);
|
||||
error = QSystemSemaphore::PermissionDenied;
|
||||
// attempting to use System V semaphores will get us a SIGSYS
|
||||
self->setError(QSystemSemaphore::PermissionDenied,
|
||||
QSystemSemaphore::tr("%1: System V semaphores are not available for "
|
||||
"sandboxed applications. Please build Qt with "
|
||||
"-feature-ipc_posix")
|
||||
.arg("QSystemSemaphore::handle:"_L1));
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (key.isEmpty()){
|
||||
errorString = QSystemSemaphore::tr("%1: key is empty")
|
||||
.arg("QSystemSemaphore::handle:"_L1);
|
||||
error = QSystemSemaphore::KeyError;
|
||||
if (self->key.isEmpty()) {
|
||||
self->setError(QSystemSemaphore::KeyError,
|
||||
QSystemSemaphore::tr("%1: key is empty")
|
||||
.arg("QSystemSemaphore::handle:"_L1));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -63,23 +64,22 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
|
|||
return unix_key;
|
||||
|
||||
// Create the file needed for ftok
|
||||
int built = QtIpcCommon::createUnixKeyFile(QFile::encodeName(fileName));
|
||||
int built = QtIpcCommon::createUnixKeyFile(QFile::encodeName(self->fileName));
|
||||
if (-1 == built) {
|
||||
errorString = QSystemSemaphore::tr("%1: unable to make key")
|
||||
.arg("QSystemSemaphore::handle:"_L1);
|
||||
error = QSystemSemaphore::KeyError;
|
||||
self->setError(QSystemSemaphore::KeyError,
|
||||
QSystemSemaphore::tr("%1: unable to make key")
|
||||
.arg("QSystemSemaphore::handle:"_L1));
|
||||
|
||||
return -1;
|
||||
}
|
||||
createdFile = (1 == built);
|
||||
|
||||
#if QT_CONFIG(sharedmemory) && !defined(QT_POSIX_IPC) && !defined(Q_OS_ANDROID)
|
||||
// Get the unix key for the created file
|
||||
unix_key = ftok(QFile::encodeName(fileName).constData(), 'Q');
|
||||
#endif
|
||||
unix_key = ftok(QFile::encodeName(self->fileName).constData(), 'Q');
|
||||
if (-1 == unix_key) {
|
||||
errorString = QSystemSemaphore::tr("%1: ftok failed")
|
||||
.arg("QSystemSemaphore::handle:"_L1);
|
||||
error = QSystemSemaphore::KeyError;
|
||||
self->setError(QSystemSemaphore::KeyError,
|
||||
QSystemSemaphore::tr("%1: ftok failed")
|
||||
.arg("QSystemSemaphore::handle:"_L1));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -89,8 +89,8 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
|
|||
if (errno == EEXIST)
|
||||
semaphore = semget(unix_key, 1, 0600 | IPC_CREAT);
|
||||
if (-1 == semaphore) {
|
||||
setErrorString("QSystemSemaphore::handle"_L1);
|
||||
cleanHandle();
|
||||
self->setUnixErrorString("QSystemSemaphore::handle"_L1);
|
||||
cleanHandle(self);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -105,12 +105,12 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
|
|||
}
|
||||
|
||||
// Created semaphore so initialize its value.
|
||||
if (createdSemaphore && initialValue >= 0) {
|
||||
if (createdSemaphore && self->initialValue >= 0) {
|
||||
qt_semun init_op;
|
||||
init_op.val = initialValue;
|
||||
init_op.val = self->initialValue;
|
||||
if (-1 == semctl(semaphore, 0, SETVAL, init_op)) {
|
||||
setErrorString("QSystemSemaphore::handle"_L1);
|
||||
cleanHandle();
|
||||
self->setUnixErrorString("QSystemSemaphore::handle"_L1);
|
||||
cleanHandle(self);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -123,22 +123,22 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
|
|||
|
||||
Cleanup the unix_key
|
||||
*/
|
||||
void QSystemSemaphorePrivate::cleanHandle()
|
||||
void QSystemSemaphoreSystemV::cleanHandle(QSystemSemaphorePrivate *self)
|
||||
{
|
||||
unix_key = -1;
|
||||
|
||||
// remove the file if we made it
|
||||
if (createdFile) {
|
||||
QFile::remove(fileName);
|
||||
QFile::remove(self->fileName);
|
||||
createdFile = false;
|
||||
}
|
||||
|
||||
if (createdSemaphore) {
|
||||
if (-1 != semaphore) {
|
||||
if (-1 == semctl(semaphore, 0, IPC_RMID, 0)) {
|
||||
setErrorString("QSystemSemaphore::cleanHandle"_L1);
|
||||
self->setUnixErrorString("QSystemSemaphore::cleanHandle"_L1);
|
||||
#if defined QSYSTEMSEMAPHORE_DEBUG
|
||||
qDebug("QSystemSemaphore::cleanHandle semctl failed.");
|
||||
qDebug("QSystemSemaphoreSystemV::cleanHandle semctl failed.");
|
||||
#endif
|
||||
}
|
||||
semaphore = -1;
|
||||
|
|
@ -150,9 +150,9 @@ void QSystemSemaphorePrivate::cleanHandle()
|
|||
/*!
|
||||
\internal
|
||||
*/
|
||||
bool QSystemSemaphorePrivate::modifySemaphore(int count)
|
||||
bool QSystemSemaphoreSystemV::modifySemaphore(QSystemSemaphorePrivate *self, int count)
|
||||
{
|
||||
if (-1 == handle())
|
||||
if (handle(self, QSystemSemaphore::Open) == -1)
|
||||
return false;
|
||||
|
||||
struct sembuf operation;
|
||||
|
|
@ -166,25 +166,23 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count)
|
|||
// If the semaphore was removed be nice and create it and then modifySemaphore again
|
||||
if (errno == EINVAL || errno == EIDRM) {
|
||||
semaphore = -1;
|
||||
cleanHandle();
|
||||
handle();
|
||||
return modifySemaphore(count);
|
||||
cleanHandle(self);
|
||||
handle(self, QSystemSemaphore::Open);
|
||||
return modifySemaphore(self, count);
|
||||
}
|
||||
setErrorString("QSystemSemaphore::modifySemaphore"_L1);
|
||||
self->setUnixErrorString("QSystemSemaphore::modifySemaphore"_L1);
|
||||
#if defined QSYSTEMSEMAPHORE_DEBUG
|
||||
qDebug("QSystemSemaphore::modify failed %d %d %d %d %d",
|
||||
qDebug("QSystemSemaphoreSystemV::modify failed %d %d %d %d %d",
|
||||
count, int(semctl(semaphore, 0, GETVAL)), int(errno), int(EIDRM), int(EINVAL);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
clearError();
|
||||
self->clearError();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_CONFIG(systemsemaphore)
|
||||
|
||||
#endif // QT_POSIX_IPC
|
||||
#endif // QT_CONFIG(sysv_sem)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
void QSystemSemaphorePrivate::setErrorString(const QString &function)
|
||||
void QSystemSemaphorePrivate::setUnixErrorString(QLatin1StringView function)
|
||||
{
|
||||
// EINVAL is handled in functions so they can give better error strings
|
||||
switch (errno) {
|
||||
|
|
@ -43,12 +43,10 @@ void QSystemSemaphorePrivate::setErrorString(const QString &function)
|
|||
errorString = QSystemSemaphore::tr("%1: out of resources").arg(function);
|
||||
error = QSystemSemaphore::OutOfResources;
|
||||
break;
|
||||
#if defined(QT_POSIX_IPC)
|
||||
case ENAMETOOLONG:
|
||||
errorString = QSystemSemaphore::tr("%1: key too long").arg(function);
|
||||
error = QSystemSemaphore::KeyError;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errorString = QSystemSemaphore::tr("%1: unknown error %2").arg(function).arg(errno);
|
||||
error = QSystemSemaphore::UnknownError;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ using namespace Qt::StringLiterals;
|
|||
|
||||
#if QT_CONFIG(systemsemaphore)
|
||||
|
||||
void QSystemSemaphorePrivate::setErrorString(const QString &function)
|
||||
void QSystemSemaphorePrivate::setWindowsErrorString(QLatin1StringView function)
|
||||
{
|
||||
BOOL windowsError = GetLastError();
|
||||
if (windowsError == 0)
|
||||
|
|
@ -38,41 +38,41 @@ void QSystemSemaphorePrivate::setErrorString(const QString &function)
|
|||
}
|
||||
}
|
||||
|
||||
HANDLE QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode)
|
||||
HANDLE QSystemSemaphoreWin32::handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode)
|
||||
{
|
||||
// don't allow making handles on empty keys
|
||||
if (key.isEmpty())
|
||||
if (self->key.isEmpty())
|
||||
return 0;
|
||||
|
||||
// Create it if it doesn't already exists.
|
||||
if (semaphore == 0) {
|
||||
semaphore = CreateSemaphore(0, initialValue, MAXLONG,
|
||||
reinterpret_cast<const wchar_t*>(fileName.utf16()));
|
||||
semaphore = CreateSemaphore(0, self->initialValue, MAXLONG,
|
||||
reinterpret_cast<const wchar_t*>(self->fileName.utf16()));
|
||||
if (semaphore == NULL)
|
||||
setErrorString("QSystemSemaphore::handle"_L1);
|
||||
self->setWindowsErrorString("QSystemSemaphore::handle"_L1);
|
||||
}
|
||||
|
||||
return semaphore;
|
||||
}
|
||||
|
||||
void QSystemSemaphorePrivate::cleanHandle()
|
||||
void QSystemSemaphoreWin32::cleanHandle(QSystemSemaphorePrivate *)
|
||||
{
|
||||
if (semaphore && !CloseHandle(semaphore)) {
|
||||
#if defined QSYSTEMSEMAPHORE_DEBUG
|
||||
qDebug("QSystemSemaphorePrivate::CloseHandle: sem failed");
|
||||
qDebug("QSystemSemaphoreWin32::CloseHandle: sem failed");
|
||||
#endif
|
||||
}
|
||||
semaphore = 0;
|
||||
}
|
||||
|
||||
bool QSystemSemaphorePrivate::modifySemaphore(int count)
|
||||
bool QSystemSemaphoreWin32::modifySemaphore(QSystemSemaphorePrivate *self, int count)
|
||||
{
|
||||
if (0 == handle())
|
||||
if (handle(self, QSystemSemaphore::Open) == nullptr)
|
||||
return false;
|
||||
|
||||
if (count > 0) {
|
||||
if (0 == ReleaseSemaphore(semaphore, count, 0)) {
|
||||
setErrorString("QSystemSemaphore::modifySemaphore"_L1);
|
||||
self->setWindowsErrorString("QSystemSemaphore::modifySemaphore"_L1);
|
||||
#if defined QSYSTEMSEMAPHORE_DEBUG
|
||||
qDebug("QSystemSemaphore::modifySemaphore ReleaseSemaphore failed");
|
||||
#endif
|
||||
|
|
@ -80,7 +80,7 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count)
|
|||
}
|
||||
} else {
|
||||
if (WAIT_OBJECT_0 != WaitForSingleObjectEx(semaphore, INFINITE, FALSE)) {
|
||||
setErrorString("QSystemSemaphore::modifySemaphore"_L1);
|
||||
self->setWindowsErrorString("QSystemSemaphore::modifySemaphore"_L1);
|
||||
#if defined QSYSTEMSEMAPHORE_DEBUG
|
||||
qDebug("QSystemSemaphore::modifySemaphore WaitForSingleObject failed");
|
||||
#endif
|
||||
|
|
@ -88,7 +88,7 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count)
|
|||
}
|
||||
}
|
||||
|
||||
clearError();
|
||||
self->clearError();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue