13#include <qcoreapplication.h>
15#if QT_CONFIG(posix_sem)
22# include "private/qcore_unix_p.h"
24# define QT_EINTR_LOOP_VAL(var, val, cmd)
26# define QT_EINTR_LOOP(var, cmd) QT_EINTR_LOOP_VAL(var, -1
, cmd)
31#if defined(Q_OS_OPENBSD) && !defined(EIDRM)
37using namespace Qt::StringLiterals;
39bool QSystemSemaphorePosix::runtimeSupportCheck()
41 static const bool result = []() {
42 sem_open(
"/", 0, 0, 0);
43 return errno != ENOSYS;
48bool QSystemSemaphorePosix::handle(QSystemSemaphorePrivate *self, QSystemSemaphore::AccessMode mode)
50 if (semaphore != SEM_FAILED)
53 const QByteArray semName = QFile::encodeName(self->nativeKey.nativeKey());
54 if (semName.isEmpty()) {
55 self->setError(QSystemSemaphore::KeyError,
56 QSystemSemaphore::tr(
"%1: key is empty")
57 .arg(
"QSystemSemaphore::handle"_L1));
62 int oflag = O_CREAT | O_EXCL;
63 for (
int tryNum = 0, maxTries = 1; tryNum < maxTries; ++tryNum) {
65 semaphore = ::sem_open(semName.constData(), oflag, 0600, self->initialValue);
66 }
while (semaphore == SEM_FAILED && errno == EINTR);
67 if (semaphore == SEM_FAILED && errno == EEXIST) {
68 if (mode == QSystemSemaphore::Create) {
69 if (::sem_unlink(semName.constData()) == -1 && errno != ENOENT) {
70 self->setUnixErrorString(
"QSystemSemaphore::handle (sem_unlink)"_L1);
87 if (semaphore == SEM_FAILED) {
88 self->setUnixErrorString(
"QSystemSemaphore::handle"_L1);
92 createdSemaphore = (oflag & O_EXCL) != 0;
97void QSystemSemaphorePosix::cleanHandle(QSystemSemaphorePrivate *self)
99 if (semaphore != SEM_FAILED) {
100 if (::sem_close(semaphore) == -1) {
101 self->setUnixErrorString(
"QSystemSemaphore::cleanHandle (sem_close)"_L1);
102#if defined QSYSTEMSEMAPHORE_DEBUG
103 qDebug(
"QSystemSemaphore::cleanHandle sem_close failed.");
106 semaphore = SEM_FAILED;
109 if (createdSemaphore) {
110 const QByteArray semName = QFile::encodeName(self->nativeKey.nativeKey());
111 if (::sem_unlink(semName) == -1 && errno != ENOENT) {
112 self->setUnixErrorString(
"QSystemSemaphore::cleanHandle (sem_unlink)"_L1);
113#if defined QSYSTEMSEMAPHORE_DEBUG
114 qDebug(
"QSystemSemaphorePosix::cleanHandle sem_unlink failed.");
117 createdSemaphore =
false;
121bool QSystemSemaphorePosix::modifySemaphore(QSystemSemaphorePrivate *self,
int count)
123 if (!handle(self, QSystemSemaphore::Open))
129 if (::sem_post(semaphore) == -1) {
130#if defined(Q_OS_VXWORKS)
131 if (errno == EINVAL) {
132 semaphore = SEM_FAILED;
133 return modifySemaphore(self, cnt);
136 self->setUnixErrorString(
"QSystemSemaphore::modifySemaphore (sem_post)"_L1);
137#if defined QSYSTEMSEMAPHORE_DEBUG
138 qDebug(
"QSystemSemaphorePosix::modify sem_post failed %d %d", count, errno);
141 for ( ; cnt < count; ++cnt) {
143 QT_EINTR_LOOP(res, ::sem_wait(semaphore));
151 QT_EINTR_LOOP(res, ::sem_wait(semaphore));
154 if (errno == EINVAL || errno == EIDRM) {
155 semaphore = SEM_FAILED;
156 return modifySemaphore(self, count);
158 self->setUnixErrorString(
"QSystemSemaphore::modifySemaphore (sem_wait)"_L1);
159#if defined QSYSTEMSEMAPHORE_DEBUG
160 qDebug(
"QSystemSemaphorePosix::modify sem_wait failed %d %d", count, errno);