11#include "qplatformdefs.h"
15#include "private/qcore_unix_p.h"
27 qErrnoWarning(code,
"%s: %s failure", where, what);
32 pthread_condattr_t *attrp =
nullptr;
34#if QT_CONFIG(pthread_condattr_setclock)
35 pthread_condattr_t condattr;
38 pthread_condattr_init(&condattr);
39 auto destroy = qScopeGuard([&] { pthread_condattr_destroy(&condattr); });
40 if (QWaitConditionClockId != CLOCK_REALTIME)
41 pthread_condattr_setclock(&condattr, QWaitConditionClockId);
57 timespec ti = deadlineToAbstime<QWaitConditionClockId>(deadline);
58 return pthread_cond_timedwait(&
cond, &
mutex, &ti);
61 bool wait(QDeadlineTimer deadline)
65 if (!deadline.isForever()) {
66 code = wait_relative(deadline);
68 code = pthread_cond_wait(&cond, &mutex);
70 if (code == 0 && wakeups == 0) {
77 Q_ASSERT_X(waiters > 0,
"QWaitCondition::wait",
"internal error (waiters)");
80 Q_ASSERT_X(
wakeups > 0,
"QWaitCondition::wait",
"internal error (wakeups)");
86 if (code && code != ETIMEDOUT)
93QWaitCondition::QWaitCondition()
95 d =
new QWaitConditionPrivate;
96 qt_report_pthread_error(pthread_mutex_init(&d->mutex,
nullptr),
"QWaitCondition",
"mutex init");
97 qt_initialize_pthread_cond(&d->cond,
"QWaitCondition");
98 d->waiters = d->wakeups = 0;
101QWaitCondition::~QWaitCondition()
103 qt_report_pthread_error(pthread_cond_destroy(&d->cond),
"QWaitCondition",
"cv destroy");
104 qt_report_pthread_error(pthread_mutex_destroy(&d->mutex),
"QWaitCondition",
"mutex destroy");
108void QWaitCondition::wakeOne()
110 qt_report_pthread_error(pthread_mutex_lock(&d->mutex),
"QWaitCondition::wakeOne()",
112 d->wakeups = qMin(d->wakeups + 1, d->waiters);
113 qt_report_pthread_error(pthread_cond_signal(&d->cond),
"QWaitCondition::wakeOne()",
115 qt_report_pthread_error(pthread_mutex_unlock(&d->mutex),
"QWaitCondition::wakeOne()",
119void QWaitCondition::wakeAll()
121 qt_report_pthread_error(pthread_mutex_lock(&d->mutex),
"QWaitCondition::wakeAll()",
123 d->wakeups = d->waiters;
124 qt_report_pthread_error(pthread_cond_broadcast(&d->cond),
"QWaitCondition::wakeAll()",
126 qt_report_pthread_error(pthread_mutex_unlock(&d->mutex),
"QWaitCondition::wakeAll()",
130bool QWaitCondition::wait(QMutex *mutex,
unsigned long time)
132 if (time == std::numeric_limits<
unsigned long>::max())
133 return wait(mutex, QDeadlineTimer(QDeadlineTimer::Forever));
134 return wait(mutex, QDeadlineTimer(time));
137bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
142 qt_report_pthread_error(pthread_mutex_lock(&d->mutex),
"QWaitCondition::wait()",
"mutex lock");
146 bool returnValue = d->wait(deadline);
153bool QWaitCondition::wait(QReadWriteLock *readWriteLock,
unsigned long time)
155 if (time == std::numeric_limits<
unsigned long>::max())
156 return wait(readWriteLock, QDeadlineTimer(QDeadlineTimer::Forever));
157 return wait(readWriteLock, QDeadlineTimer(time));
160bool QWaitCondition::wait(QReadWriteLock *readWriteLock, QDeadlineTimer deadline)
162 using namespace QReadWriteLockStates;
166 auto previousState = QReadWriteLockPrivate::stateForWaitCondition(readWriteLock);
167 if (previousState == Unlocked)
169 if (previousState == RecursivelyLocked) {
170 qWarning(
"QWaitCondition: cannot wait on QReadWriteLocks with recursive lockForWrite()");
174 qt_report_pthread_error(pthread_mutex_lock(&d->mutex),
"QWaitCondition::wait()",
"mutex lock");
177 readWriteLock->unlock();
179 bool returnValue = d->wait(deadline);
181 if (previousState == LockedForWrite)
182 readWriteLock->lockForWrite();
184 readWriteLock->lockForRead();
bool wait(QDeadlineTimer deadline)
int wait_relative(QDeadlineTimer deadline)
static void qt_initialize_pthread_cond(pthread_cond_t *cond, const char *where)
static QT_BEGIN_NAMESPACE void qt_report_pthread_error(int code, const char *where, const char *what)