Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qsystemsemaphore.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qsystemsemaphore.h"
6
7#if QT_CONFIG(systemsemaphore)
8#include <QtCore/q20memory.h>
9
11
12using namespace QtIpcCommon;
13using namespace Qt::StringLiterals;
14
15inline void QSystemSemaphorePrivate::constructBackend()
16{
17 visit([](auto p) { q20::construct_at(p); });
18}
19
20inline void QSystemSemaphorePrivate::destructBackend()
21{
22 visit([](auto p) { std::destroy_at(p); });
23}
24
74QSystemSemaphore::QSystemSemaphore(const QString &key, int initialValue, AccessMode mode)
75 : QSystemSemaphore(legacyNativeKey(key), initialValue, mode)
76{
77}
78
115QSystemSemaphore::QSystemSemaphore(const QNativeIpcKey &key, int initialValue, AccessMode mode)
116 : d(new QSystemSemaphorePrivate(key.type()))
117{
118 setNativeKey(key, initialValue, mode);
119}
120
136QSystemSemaphore::~QSystemSemaphore()
137{
138 d->cleanHandle();
139}
140
178void QSystemSemaphore::setNativeKey(const QNativeIpcKey &key, int initialValue, AccessMode mode)
179{
180 if (key == d->nativeKey && mode == Open)
181 return;
182 if (!isKeyTypeSupported(key.type())) {
183 d->setError(KeyError, tr("%1: unsupported key type")
184 .arg("QSystemSemaphore::setNativeKey"_L1));
185 return;
186 }
187
188 d->clearError();
189 d->cleanHandle();
190 if (key.type() == d->nativeKey.type()) {
191 // we can reuse the backend
192 d->nativeKey = key;
193 } else {
194 // we must recreate the backend
195 d->destructBackend();
196 d->nativeKey = key;
197 d->constructBackend();
198 }
199 d->initialValue = initialValue;
200 d->handle(mode);
201}
202
213QNativeIpcKey QSystemSemaphore::nativeIpcKey() const
214{
215 return d->nativeKey;
216}
217
228void QSystemSemaphore::setKey(const QString &key, int initialValue, AccessMode mode)
229{
230 setNativeKey(legacyNativeKey(key), initialValue, mode);
231}
232
239QString QSystemSemaphore::key() const
240{
241 return QNativeIpcKeyPrivate::legacyKey(d->nativeKey);
242}
243
257bool QSystemSemaphore::acquire()
258{
259 return d->modifySemaphore(-1);
260}
261
283bool QSystemSemaphore::release(int n)
284{
285 if (n == 0)
286 return true;
287 if (n < 0) {
288 qWarning("QSystemSemaphore::release: n is negative.");
289 return false;
290 }
291 return d->modifySemaphore(n);
292}
293
300QSystemSemaphore::SystemSemaphoreError QSystemSemaphore::error() const
301{
302 return d->error;
303}
304
335QString QSystemSemaphore::errorString() const
336{
337 return d->errorString;
338}
339
340void QSystemSemaphorePrivate::setUnixErrorString(QLatin1StringView function)
341{
342 // EINVAL is handled in functions so they can give better error strings
343 switch (errno) {
344 case EPERM:
345 case EACCES:
346 errorString = QSystemSemaphore::tr("%1: permission denied").arg(function);
347 error = QSystemSemaphore::PermissionDenied;
348 break;
349 case EEXIST:
350 errorString = QSystemSemaphore::tr("%1: already exists").arg(function);
351 error = QSystemSemaphore::AlreadyExists;
352 break;
353 case ENOENT:
354 errorString = QSystemSemaphore::tr("%1: does not exist").arg(function);
355 error = QSystemSemaphore::NotFound;
356 break;
357 case ERANGE:
358 case ENOSPC:
359 case EMFILE:
360 errorString = QSystemSemaphore::tr("%1: out of resources").arg(function);
361 error = QSystemSemaphore::OutOfResources;
362 break;
363 case ENAMETOOLONG:
364 errorString = QSystemSemaphore::tr("%1: key too long").arg(function);
365 error = QSystemSemaphore::KeyError;
366 break;
367 default:
368 errorString = QSystemSemaphore::tr("%1: unknown error: %2")
369 .arg(function, qt_error_string(errno));
370 error = QSystemSemaphore::UnknownError;
371#if defined QSYSTEMSEMAPHORE_DEBUG
372 qDebug() << errorString << "key" << key << "errno" << errno << EINVAL;
373#endif
374 }
375}
376
377bool QSystemSemaphore::isKeyTypeSupported(QNativeIpcKey::Type type)
378{
379 if (!isIpcSupported(IpcType::SystemSemaphore, type))
380 return false;
381 using Variant = decltype(QSystemSemaphorePrivate::backend);
382 return Variant::staticVisit(type, [](auto ptr) {
383 using Impl = std::decay_t<decltype(*ptr)>;
384 return Impl::runtimeSupportCheck();
385 });
386}
387
388QNativeIpcKey QSystemSemaphore::platformSafeKey(const QString &key, QNativeIpcKey::Type type)
389{
390 return QtIpcCommon::platformSafeKey(key, IpcType::SystemSemaphore, type);
391}
392
393QNativeIpcKey QSystemSemaphore::legacyNativeKey(const QString &key, QNativeIpcKey::Type type)
394{
395 return QtIpcCommon::legacyPlatformSafeKey(key, IpcType::SystemSemaphore, type);
396}
397
399
400#include "moc_qsystemsemaphore.cpp"
401
402#endif // QT_CONFIG(systemsemaphore)
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
auto visit(Fn &&fn, QIODevice *socket, Args &&...args)
Combined button and popup list for selecting options.
Q_MULTIMEDIA_EXPORT QString errorString(HRESULT hr)
T * construct_at(T *ptr, Args &&... args)
Definition q20memory.h:41
DBusConnection const char DBusError * error
Q_DECL_COLD_FUNCTION Q_CORE_EXPORT QString qt_error_string(int errorCode=-1)
#define qDebug
[1]
Definition qlogging.h:164
#define qWarning
Definition qlogging.h:166
static ControlElement< T > * ptr(QWidget *widget)
GLenum mode
GLuint64 key
GLenum type
GLfloat n
GLfloat GLfloat p
[1]
SSL_CTX int void * arg
#define tr(X)