mirror of
https://bitbucket.org/smil3y/katie.git
synced 2025-02-24 19:02:59 +00:00
effectively revert QWaitCondition changes
Signed-off-by: Ivailo Monev <xakepa10@laimg.moc>
This commit is contained in:
parent
8e18728348
commit
53aa704af0
2 changed files with 78 additions and 29 deletions
|
@ -25,6 +25,12 @@ static inline QString fromstrerror_helper(const char *str, const QByteArray &)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline void report_error(int code, const char *where, const char *what)
|
||||||
|
{
|
||||||
|
if (code != 0)
|
||||||
|
qWarning("%s: %s failure: %s", where, what, qPrintable(qt_error_string(code)));
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // QCORECOMMON_P_H
|
#endif // QCORECOMMON_P_H
|
||||||
|
|
|
@ -31,13 +31,16 @@
|
||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qplatformdefs.h"
|
||||||
#include "qwaitcondition.h"
|
#include "qwaitcondition.h"
|
||||||
#include "qmutex.h"
|
#include "qmutex.h"
|
||||||
#include "qreadwritelock.h"
|
#include "qreadwritelock.h"
|
||||||
|
#include "qatomic.h"
|
||||||
|
#include "qstring.h"
|
||||||
#include "qreadwritelock_p.h"
|
#include "qreadwritelock_p.h"
|
||||||
|
#include "qcorecommon_p.h"
|
||||||
|
|
||||||
#include <condition_variable>
|
#include <errno.h>
|
||||||
#include <chrono>
|
|
||||||
|
|
||||||
#ifndef QT_NO_THREAD
|
#ifndef QT_NO_THREAD
|
||||||
|
|
||||||
|
@ -45,32 +48,83 @@ QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QWaitConditionPrivate {
|
class QWaitConditionPrivate {
|
||||||
public:
|
public:
|
||||||
std::mutex mutex;
|
pthread_mutex_t mutex;
|
||||||
std::condition_variable cond;
|
pthread_cond_t cond;
|
||||||
|
int waiters;
|
||||||
|
int wakeups;
|
||||||
|
|
||||||
|
bool wait(unsigned long time)
|
||||||
|
{
|
||||||
|
int code;
|
||||||
|
forever {
|
||||||
|
if (time != ULONG_MAX) {
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, Q_NULLPTR);
|
||||||
|
|
||||||
|
timespec ti;
|
||||||
|
ti.tv_nsec = (tv.tv_usec + (time % 1000) * 1000) * 1000;
|
||||||
|
ti.tv_sec = tv.tv_sec + (time / 1000) + (ti.tv_nsec / 1000000000);
|
||||||
|
ti.tv_nsec %= 1000000000;
|
||||||
|
|
||||||
|
code = pthread_cond_timedwait(&cond, &mutex, &ti);
|
||||||
|
} else {
|
||||||
|
code = pthread_cond_wait(&cond, &mutex);
|
||||||
|
}
|
||||||
|
if (code == 0 && wakeups == 0) {
|
||||||
|
// many vendors warn of spurios wakeups from
|
||||||
|
// pthread_cond_wait(), especially after signal delivery,
|
||||||
|
// even though POSIX doesn't allow for it... sigh
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT_X(waiters > 0, "QWaitCondition::wait", "internal error (waiters)");
|
||||||
|
--waiters;
|
||||||
|
if (code == 0) {
|
||||||
|
Q_ASSERT_X(wakeups > 0, "QWaitCondition::wait", "internal error (wakeups)");
|
||||||
|
--wakeups;
|
||||||
|
}
|
||||||
|
report_error(pthread_mutex_unlock(&mutex), "QWaitCondition::wait()", "mutex unlock");
|
||||||
|
|
||||||
|
if (code && code != ETIMEDOUT)
|
||||||
|
report_error(code, "QWaitCondition::wait()", "cv wait");
|
||||||
|
|
||||||
|
return (code == 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
QWaitCondition::QWaitCondition()
|
QWaitCondition::QWaitCondition()
|
||||||
: d(new QWaitConditionPrivate)
|
|
||||||
{
|
{
|
||||||
|
d = new QWaitConditionPrivate;
|
||||||
|
report_error(pthread_mutex_init(&d->mutex, NULL), "QWaitCondition", "mutex init");
|
||||||
|
report_error(pthread_cond_init(&d->cond, NULL), "QWaitCondition", "cv init");
|
||||||
|
d->waiters = d->wakeups = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QWaitCondition::~QWaitCondition()
|
QWaitCondition::~QWaitCondition()
|
||||||
{
|
{
|
||||||
|
report_error(pthread_cond_destroy(&d->cond), "QWaitCondition", "cv destroy");
|
||||||
|
report_error(pthread_mutex_destroy(&d->mutex), "QWaitCondition", "mutex destroy");
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaitCondition::wakeOne()
|
void QWaitCondition::wakeOne()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(d->mutex);
|
report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wakeOne()", "mutex lock");
|
||||||
d->cond.notify_one();
|
d->wakeups = qMin(d->wakeups + 1, d->waiters);
|
||||||
|
report_error(pthread_cond_signal(&d->cond), "QWaitCondition::wakeOne()", "cv signal");
|
||||||
|
report_error(pthread_mutex_unlock(&d->mutex), "QWaitCondition::wakeOne()", "mutex unlock");
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaitCondition::wakeAll()
|
void QWaitCondition::wakeAll()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(d->mutex);
|
report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wakeAll()", "mutex lock");
|
||||||
d->cond.notify_all();
|
d->wakeups = d->waiters;
|
||||||
|
report_error(pthread_cond_broadcast(&d->cond), "QWaitCondition::wakeAll()", "cv broadcast");
|
||||||
|
report_error(pthread_mutex_unlock(&d->mutex), "QWaitCondition::wakeAll()", "mutex unlock");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
|
bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
|
||||||
|
@ -82,21 +136,15 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wait()", "mutex lock");
|
||||||
|
++d->waiters;
|
||||||
mutex->unlock();
|
mutex->unlock();
|
||||||
|
|
||||||
std::unique_lock<std::mutex> lock(d->mutex);
|
bool returnValue = d->wait(time);
|
||||||
|
|
||||||
std::cv_status returnValue;
|
|
||||||
if (time != ULONG_MAX) {
|
|
||||||
returnValue = d->cond.wait_for(lock, std::chrono::milliseconds(time));
|
|
||||||
} else {
|
|
||||||
returnValue = std::cv_status::no_timeout;
|
|
||||||
d->cond.wait(lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex->lock();
|
mutex->lock();
|
||||||
|
|
||||||
return returnValue == std::cv_status::no_timeout;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
|
bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
|
||||||
|
@ -108,25 +156,20 @@ bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wait()", "mutex lock");
|
||||||
|
++d->waiters;
|
||||||
|
|
||||||
int previousAccessCount = readWriteLock->d->accessCount;
|
int previousAccessCount = readWriteLock->d->accessCount;
|
||||||
readWriteLock->unlock();
|
readWriteLock->unlock();
|
||||||
|
|
||||||
std::unique_lock<std::mutex> lock(d->mutex);
|
bool returnValue = d->wait(time);
|
||||||
|
|
||||||
std::cv_status returnValue;
|
|
||||||
if (time != ULONG_MAX) {
|
|
||||||
returnValue = d->cond.wait_for(lock, std::chrono::milliseconds(time));
|
|
||||||
} else {
|
|
||||||
returnValue = std::cv_status::no_timeout;
|
|
||||||
d->cond.wait(lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (previousAccessCount < 0)
|
if (previousAccessCount < 0)
|
||||||
readWriteLock->lockForWrite();
|
readWriteLock->lockForWrite();
|
||||||
else
|
else
|
||||||
readWriteLock->lockForRead();
|
readWriteLock->lockForRead();
|
||||||
|
|
||||||
return returnValue == std::cv_status::no_timeout;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
Loading…
Add table
Reference in a new issue