summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/global/qglobal.cpp2
-rw-r--r--src/corelib/io/qfilesystemwatcher.cpp4
-rw-r--r--src/corelib/io/qfilesystemwatcher_inotify.cpp2
-rw-r--r--src/corelib/itemmodels/qitemselectionmodel.cpp28
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp4
-rw-r--r--src/corelib/json/qjsondocument.cpp2
-rw-r--r--src/corelib/json/qjsonparser.cpp4
-rw-r--r--src/corelib/kernel/qppsobject.cpp28
-rw-r--r--src/corelib/kernel/qppsobjectprivate_p.h4
-rw-r--r--src/corelib/kernel/qsystemsemaphore_posix.cpp4
-rw-r--r--src/corelib/kernel/qsystemsemaphore_systemv.cpp2
-rw-r--r--src/corelib/kernel/qsystemsemaphore_win.cpp6
-rw-r--r--src/corelib/mimetypes/qmimemagicrule.cpp10
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp2
-rw-r--r--src/corelib/mimetypes/qmimetypeparser.cpp4
-rw-r--r--src/corelib/thread/qreadwritelock.cpp528
-rw-r--r--src/corelib/thread/qreadwritelock.h6
-rw-r--r--src/corelib/thread/qreadwritelock_p.h39
-rw-r--r--src/corelib/thread/qwaitcondition_unix.cpp10
-rw-r--r--src/corelib/thread/qwaitcondition_win.cpp10
-rw-r--r--src/corelib/tools/qcollator_macx.cpp4
-rw-r--r--src/corelib/tools/qcollator_win.cpp2
-rw-r--r--src/corelib/tools/qmap.h4
-rw-r--r--src/corelib/tools/qtimeline.cpp2
24 files changed, 458 insertions, 253 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index cbcc6d02a6..35213f8a4c 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -426,7 +426,7 @@ Q_STATIC_ASSERT_X(QT_POINTER_SIZE == sizeof(void *), "QT_POINTER_SIZE defined in
*/
/*!
- \fn QFlags QFlags::setFlag(Enum flag, bool on) const
+ \fn QFlags QFlags::setFlag(Enum flag, bool on)
\since 5.7
Sets the indicated \a flag if \a on is \c true or unsets it if
diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp
index e26d412cf9..8b11830fbe 100644
--- a/src/corelib/io/qfilesystemwatcher.cpp
+++ b/src/corelib/io/qfilesystemwatcher.cpp
@@ -317,11 +317,11 @@ QStringList QFileSystemWatcher::addPaths(const QStringList &paths)
// Autotest override case - use the explicitly selected engine only
const QStringRef forceName = on.midRef(26);
if(forceName == QLatin1String("poller")) {
- qDebug() << "QFileSystemWatcher: skipping native engine, using only polling engine";
+ qDebug("QFileSystemWatcher: skipping native engine, using only polling engine");
d_func()->initPollerEngine();
engine = d->poller;
} else if(forceName == QLatin1String("native")) {
- qDebug() << "QFileSystemWatcher: skipping polling engine, using only native engine";
+ qDebug("QFileSystemWatcher: skipping polling engine, using only native engine");
engine = d->native;
}
}
diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp
index 791429cc5a..5564bc7dca 100644
--- a/src/corelib/io/qfilesystemwatcher_inotify.cpp
+++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp
@@ -344,7 +344,7 @@ QStringList QInotifyFileSystemWatcherEngine::removePaths(const QStringList &path
void QInotifyFileSystemWatcherEngine::readFromInotify()
{
- // qDebug() << "QInotifyFileSystemWatcherEngine::readFromInotify";
+ // qDebug("QInotifyFileSystemWatcherEngine::readFromInotify");
int buffSize = 0;
ioctl(inotifyFd, FIONREAD, (char *) &buffSize);
diff --git a/src/corelib/itemmodels/qitemselectionmodel.cpp b/src/corelib/itemmodels/qitemselectionmodel.cpp
index dd913f957b..b2aacfa5aa 100644
--- a/src/corelib/itemmodels/qitemselectionmodel.cpp
+++ b/src/corelib/itemmodels/qitemselectionmodel.cpp
@@ -327,6 +327,15 @@ static void indexesFromRange(const QItemSelectionRange &range, ModelIndexContain
}
}
+template<typename ModelIndexContainer>
+static ModelIndexContainer qSelectionIndexes(const QItemSelection &selection)
+{
+ ModelIndexContainer result;
+ for (const auto &range : selection)
+ indexesFromRange(range, result);
+ return result;
+}
+
/*!
Returns \c true if the selection range contains no selectable item
\since 4.7
@@ -469,20 +478,7 @@ bool QItemSelection::contains(const QModelIndex &index) const
QModelIndexList QItemSelection::indexes() const
{
- QModelIndexList result;
- QList<QItemSelectionRange>::const_iterator it = begin();
- for (; it != end(); ++it)
- indexesFromRange(*it, result);
- return result;
-}
-
-static QVector<QPersistentModelIndex> qSelectionPersistentindexes(const QItemSelection &sel)
-{
- QVector<QPersistentModelIndex> result;
- QList<QItemSelectionRange>::const_iterator it = sel.constBegin();
- for (; it != sel.constEnd(); ++it)
- indexesFromRange(*it, result);
- return result;
+ return qSelectionIndexes<QModelIndexList>(*this);
}
static QVector<QPair<QPersistentModelIndex, uint> > qSelectionPersistentRowLengths(const QItemSelection &sel)
@@ -892,8 +888,8 @@ void QItemSelectionModelPrivate::_q_layoutAboutToBeChanged(const QList<QPersiste
savedPersistentRowLengths = qSelectionPersistentRowLengths(ranges);
savedPersistentCurrentRowLengths = qSelectionPersistentRowLengths(currentSelection);
} else {
- savedPersistentIndexes = qSelectionPersistentindexes(ranges);
- savedPersistentCurrentIndexes = qSelectionPersistentindexes(currentSelection);
+ savedPersistentIndexes = qSelectionIndexes<QVector<QPersistentModelIndex>>(ranges);
+ savedPersistentCurrentIndexes = qSelectionIndexes<QVector<QPersistentModelIndex>>(currentSelection);
}
}
/*!
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index dc159c8f7c..18cb49d483 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -376,7 +376,7 @@ QModelIndex QSortFilterProxyModelPrivate::proxy_to_source(const QModelIndex &pro
if (!proxy_index.isValid())
return QModelIndex(); // for now; we may want to be able to set a root index later
if (proxy_index.model() != q_func()) {
- qWarning() << "QSortFilterProxyModel: index from wrong model passed to mapToSource";
+ qWarning("QSortFilterProxyModel: index from wrong model passed to mapToSource");
Q_ASSERT(!"QSortFilterProxyModel: index from wrong model passed to mapToSource");
return QModelIndex();
}
@@ -394,7 +394,7 @@ QModelIndex QSortFilterProxyModelPrivate::source_to_proxy(const QModelIndex &sou
if (!source_index.isValid())
return QModelIndex(); // for now; we may want to be able to set a root index later
if (source_index.model() != model) {
- qWarning() << "QSortFilterProxyModel: index from wrong model passed to mapFromSource";
+ qWarning("QSortFilterProxyModel: index from wrong model passed to mapFromSource");
Q_ASSERT(!"QSortFilterProxyModel: index from wrong model passed to mapFromSource");
return QModelIndex();
}
diff --git a/src/corelib/json/qjsondocument.cpp b/src/corelib/json/qjsondocument.cpp
index 1fde69ecf6..b2fa16d22a 100644
--- a/src/corelib/json/qjsondocument.cpp
+++ b/src/corelib/json/qjsondocument.cpp
@@ -184,7 +184,7 @@ QJsonDocument &QJsonDocument::operator =(const QJsonDocument &other)
QJsonDocument QJsonDocument::fromRawData(const char *data, int size, DataValidation validation)
{
if (quintptr(data) & 3) {
- qWarning() <<"QJsonDocument::fromRawData: data has to have 4 byte alignment";
+ qWarning("QJsonDocument::fromRawData: data has to have 4 byte alignment");
return QJsonDocument();
}
diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp
index a896d17519..2926adf10a 100644
--- a/src/corelib/json/qjsonparser.cpp
+++ b/src/corelib/json/qjsonparser.cpp
@@ -300,7 +300,7 @@ QJsonDocument Parser::parse(QJsonParseError *error)
{
#ifdef PARSER_DEBUG
indent = 0;
- qDebug() << ">>>>> parser begin";
+ qDebug(">>>>> parser begin");
#endif
// allocate some space
dataLength = qMax(end - json, (ptrdiff_t) 256);
@@ -346,7 +346,7 @@ QJsonDocument Parser::parse(QJsonParseError *error)
error:
#ifdef PARSER_DEBUG
- qDebug() << ">>>>> parser error";
+ qDebug(">>>>> parser error");
#endif
if (error) {
error->offset = json - head;
diff --git a/src/corelib/kernel/qppsobject.cpp b/src/corelib/kernel/qppsobject.cpp
index 5990deb9c3..dbff997c88 100644
--- a/src/corelib/kernel/qppsobject.cpp
+++ b/src/corelib/kernel/qppsobject.cpp
@@ -72,7 +72,7 @@ public:
{
int fd = qt_safe_open("/pps/.all", O_RDONLY);
if (fd == -1) {
- qWarning() << "qppsobject.cpp: qt_safe_open failed";
+ qWarning("qppsobject.cpp: qt_safe_open failed");
value = -1;
}
@@ -114,7 +114,7 @@ QPpsAttributeMap QPpsObjectPrivate::decode(const QByteArray &rawData, bool *ok)
// no need to check ok in this case
attributeMap = decodeObject(&decoder, ok);
} else {
- qWarning() << "QPpsObjectPrivate::decode: pps_decoder_initialize failed";
+ qWarning("QPpsObjectPrivate::decode: pps_decoder_initialize failed");
*ok = false;
}
@@ -162,7 +162,7 @@ QPpsAttribute QPpsObjectPrivate::decodeString(pps_decoder_t *decoder)
pps_decoder_error_t error = pps_decoder_get_string(decoder, 0, &value);
if (error != PPS_DECODER_OK) {
- qWarning() << "QPpsObjectPrivate::decodeString: PPS_DECODER_GET_STRING failed";
+ qWarning("QPpsObjectPrivate::decodeString: PPS_DECODER_GET_STRING failed");
return QPpsAttribute();
}
@@ -189,19 +189,19 @@ QPpsAttribute QPpsObjectPrivate::decodeNumber(pps_decoder_t *decoder)
case PPS_DECODER_CONVERSION_FAILED:
error = pps_decoder_get_int64(decoder, 0, &llValue);
if (error != PPS_DECODER_OK) {
- qWarning() << "QPpsObjectPrivate::decodeNumber: failed to decode integer";
+ qWarning("QPpsObjectPrivate::decodeNumber: failed to decode integer");
return QPpsAttribute();
}
flags = readFlags(decoder);
return QPpsAttributePrivate::createPpsAttribute(llValue, flags);
default:
- qWarning() << "QPpsObjectPrivate::decodeNumber: pps_decoder_get_int failed";
+ qWarning("QPpsObjectPrivate::decodeNumber: pps_decoder_get_int failed");
return QPpsAttribute();
}
} else {
pps_decoder_error_t error = pps_decoder_get_double(decoder, 0, &dValue);
if (error != PPS_DECODER_OK) {
- qWarning() << "QPpsObjectPrivate::decodeNumber: pps_decoder_get_double failed";
+ qWarning("QPpsObjectPrivate::decodeNumber: pps_decoder_get_double failed");
return QPpsAttribute();
}
flags = readFlags(decoder);
@@ -215,7 +215,7 @@ QPpsAttribute QPpsObjectPrivate::decodeBool(pps_decoder_t *decoder)
pps_decoder_error_t error = pps_decoder_get_bool(decoder, 0, &value);
if (error != PPS_DECODER_OK) {
- qWarning() << "QPpsObjectPrivate::decodeBool: pps_decoder_get_bool failed";
+ qWarning("QPpsObjectPrivate::decodeBool: pps_decoder_get_bool failed");
return QPpsAttribute();
}
@@ -278,7 +278,7 @@ QPpsAttribute QPpsObjectPrivate::decodeData(pps_decoder_t *decoder)
case PPS_TYPE_NONE:
case PPS_TYPE_UNKNOWN:
default:
- qWarning() << "QPpsObjectPrivate::decodeData: invalid pps_node_type";
+ qWarning("QPpsObjectPrivate::decodeData: invalid pps_node_type");
return QPpsAttribute();
}
}
@@ -292,7 +292,7 @@ QPpsAttributeList QPpsObjectPrivate::decodeArray(pps_decoder_t *decoder, bool *o
// Force movement to a specific index.
pps_decoder_error_t error = pps_decoder_goto_index(decoder, i);
if (error != PPS_DECODER_OK) {
- qWarning() << "QPpsObjectPrivate::decodeArray: pps_decoder_goto_index failed";
+ qWarning("QPpsObjectPrivate::decodeArray: pps_decoder_goto_index failed");
*ok = false;
return QPpsAttributeList();
}
@@ -319,7 +319,7 @@ QPpsAttributeMap QPpsObjectPrivate::decodeObject(pps_decoder_t *decoder, bool *o
// Force movement to a specific index.
pps_decoder_error_t error = pps_decoder_goto_index(decoder, i);
if (error != PPS_DECODER_OK) {
- qWarning() << "QPpsObjectPrivate::decodeObject: pps_decoder_goto_index failed";
+ qWarning("QPpsObjectPrivate::decodeObject: pps_decoder_goto_index failed");
*ok = false;
return QPpsAttributeMap();
}
@@ -368,7 +368,7 @@ QVariant QPpsObjectPrivate::variantFromPpsAttribute(const QPpsAttribute &attribu
return variantMapFromPpsAttributeMap(attribute.toMap());
case QPpsAttribute::None:
default:
- qWarning() << "QPpsObjectPrivate::variantFromPpsAttribute: invalid attribute parameter";
+ qWarning("QPpsObjectPrivate::variantFromPpsAttribute: invalid attribute parameter");
return QVariant();
}
}
@@ -385,7 +385,7 @@ QByteArray QPpsObjectPrivate::encode(const QVariantMap &ppsData, bool *ok)
// The memory will be freed when pps_encoder_cleanup is called.
rawData = pps_encoder_buffer(&encoder);
if (!rawData) {
- qWarning() << "QPpsObjectPrivate::encode: pps_encoder_buffer failed";
+ qWarning("QPpsObjectPrivate::encode: pps_encoder_buffer failed");
*ok = false;
}
}
@@ -448,7 +448,7 @@ void QPpsObjectPrivate::encodeData(pps_encoder_t *encoder, const char *name, con
errorFunction = QStringLiteral("pps_encoder_add_null");
break;
default:
- qWarning() << "QPpsObjectPrivate::encodeData: the type of the parameter data is invalid";
+ qWarning("QPpsObjectPrivate::encodeData: the type of the parameter data is invalid");
*ok = false;
return;
}
@@ -685,7 +685,7 @@ QByteArray QPpsObject::read(bool *ok)
const int maxSize = ppsMaxSize->value;
if (maxSize == -1) {
- qWarning() << "QPpsObject::read: maxSize is equal to -1";
+ qWarning("QPpsObject::read: maxSize is equal to -1");
safeAssign(ok, false);
return QByteArray();
}
diff --git a/src/corelib/kernel/qppsobjectprivate_p.h b/src/corelib/kernel/qppsobjectprivate_p.h
index 26d89ab7f0..e1d54e58de 100644
--- a/src/corelib/kernel/qppsobjectprivate_p.h
+++ b/src/corelib/kernel/qppsobjectprivate_p.h
@@ -105,7 +105,7 @@ inline bool QPpsObjectPrivate::decoderPush(pps_decoder_t *decoder, const char *n
{
pps_decoder_error_t error = pps_decoder_push(decoder, name);
if (error != PPS_DECODER_OK) {
- qWarning() << "QPpsObjectPrivate::decodeData: pps_decoder_push failed";
+ qWarning("QPpsObjectPrivate::decodeData: pps_decoder_push failed");
return false;
}
return true;
@@ -115,7 +115,7 @@ inline bool QPpsObjectPrivate::decoderPop(pps_decoder_t *decoder)
{
pps_decoder_error_t error = pps_decoder_pop(decoder);
if (error != PPS_DECODER_OK) {
- qWarning() << "QPpsObjectPrivate::decodeData: pps_decoder_pop failed";
+ qWarning("QPpsObjectPrivate::decodeData: pps_decoder_pop failed");
return false;
}
return true;
diff --git a/src/corelib/kernel/qsystemsemaphore_posix.cpp b/src/corelib/kernel/qsystemsemaphore_posix.cpp
index 76ab0d42eb..6137239467 100644
--- a/src/corelib/kernel/qsystemsemaphore_posix.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_posix.cpp
@@ -119,7 +119,7 @@ void QSystemSemaphorePrivate::cleanHandle()
if (::sem_close(semaphore) == -1) {
setErrorString(QLatin1String("QSystemSemaphore::cleanHandle (sem_close)"));
#if defined QSYSTEMSEMAPHORE_DEBUG
- qDebug() << QLatin1String("QSystemSemaphore::cleanHandle sem_close failed.");
+ qDebug("QSystemSemaphore::cleanHandle sem_close failed.");
#endif
}
semaphore = SEM_FAILED;
@@ -129,7 +129,7 @@ void QSystemSemaphorePrivate::cleanHandle()
if (::sem_unlink(QFile::encodeName(fileName).constData()) == -1 && errno != ENOENT) {
setErrorString(QLatin1String("QSystemSemaphore::cleanHandle (sem_unlink)"));
#if defined QSYSTEMSEMAPHORE_DEBUG
- qDebug() << QLatin1String("QSystemSemaphore::cleanHandle sem_unlink failed.");
+ qDebug("QSystemSemaphore::cleanHandle sem_unlink failed.");
#endif
}
createdSemaphore = false;
diff --git a/src/corelib/kernel/qsystemsemaphore_systemv.cpp b/src/corelib/kernel/qsystemsemaphore_systemv.cpp
index 69e1bf7705..f4fdfa5f58 100644
--- a/src/corelib/kernel/qsystemsemaphore_systemv.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_systemv.cpp
@@ -153,7 +153,7 @@ void QSystemSemaphorePrivate::cleanHandle()
if (-1 == semctl(semaphore, 0, IPC_RMID, 0)) {
setErrorString(QLatin1String("QSystemSemaphore::cleanHandle"));
#if defined QSYSTEMSEMAPHORE_DEBUG
- qDebug() << QLatin1String("QSystemSemaphore::cleanHandle semctl failed.");
+ qDebug("QSystemSemaphore::cleanHandle semctl failed.");
#endif
}
semaphore = -1;
diff --git a/src/corelib/kernel/qsystemsemaphore_win.cpp b/src/corelib/kernel/qsystemsemaphore_win.cpp
index ca31e9d59d..236e346afe 100644
--- a/src/corelib/kernel/qsystemsemaphore_win.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_win.cpp
@@ -101,7 +101,7 @@ void QSystemSemaphorePrivate::cleanHandle()
{
if (semaphore && !CloseHandle(semaphore)) {
#if defined QSYSTEMSEMAPHORE_DEBUG
- qDebug() << QLatin1String("QSystemSemaphorePrivate::CloseHandle: sem failed");
+ qDebug("QSystemSemaphorePrivate::CloseHandle: sem failed");
#endif
}
semaphore = 0;
@@ -116,7 +116,7 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count)
if (0 == ReleaseSemaphore(semaphore, count, 0)) {
setErrorString(QLatin1String("QSystemSemaphore::modifySemaphore"));
#if defined QSYSTEMSEMAPHORE_DEBUG
- qDebug() << QLatin1String("QSystemSemaphore::modifySemaphore ReleaseSemaphore failed");
+ qDebug("QSystemSemaphore::modifySemaphore ReleaseSemaphore failed");
#endif
return false;
}
@@ -128,7 +128,7 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count)
#endif
setErrorString(QLatin1String("QSystemSemaphore::modifySemaphore"));
#if defined QSYSTEMSEMAPHORE_DEBUG
- qDebug() << QLatin1String("QSystemSemaphore::modifySemaphore WaitForSingleObject failed");
+ qDebug("QSystemSemaphore::modifySemaphore WaitForSingleObject failed");
#endif
return false;
}
diff --git a/src/corelib/mimetypes/qmimemagicrule.cpp b/src/corelib/mimetypes/qmimemagicrule.cpp
index 4ba98ad2c4..0db3407b7b 100644
--- a/src/corelib/mimetypes/qmimemagicrule.cpp
+++ b/src/corelib/mimetypes/qmimemagicrule.cpp
@@ -234,7 +234,7 @@ QMimeMagicRule::QMimeMagicRule(const QString &type,
m_mask(mask),
m_matchFunction(nullptr)
{
- if (m_type == Invalid)
+ if (Q_UNLIKELY(m_type == Invalid))
*errorString = QLatin1String("Type ") + type + QLatin1String(" is not supported");
// Parse for offset as "1" or "1:10"
@@ -247,7 +247,7 @@ QMimeMagicRule::QMimeMagicRule(const QString &type,
return;
}
- if (m_value.isEmpty()) {
+ if (Q_UNLIKELY(m_value.isEmpty())) {
m_type = Invalid;
if (errorString)
*errorString = QStringLiteral("Invalid empty magic rule value");
@@ -257,7 +257,7 @@ QMimeMagicRule::QMimeMagicRule(const QString &type,
if (m_type >= Host16 && m_type <= Byte) {
bool ok;
m_number = m_value.toUInt(&ok, 0); // autodetect base
- if (!ok) {
+ if (Q_UNLIKELY(!ok)) {
m_type = Invalid;
if (errorString)
*errorString = QLatin1String("Invalid magic rule value \"") + QLatin1String(m_value) + QLatin1Char('"');
@@ -271,7 +271,7 @@ QMimeMagicRule::QMimeMagicRule(const QString &type,
m_pattern = makePattern(m_value);
m_pattern.squeeze();
if (!m_mask.isEmpty()) {
- if (m_mask.size() < 4 || !m_mask.startsWith("0x")) {
+ if (Q_UNLIKELY(m_mask.size() < 4 || !m_mask.startsWith("0x"))) {
m_type = Invalid;
if (errorString)
*errorString = QLatin1String("Invalid magic rule mask \"") + QLatin1String(m_mask) + QLatin1Char('"');
@@ -279,7 +279,7 @@ QMimeMagicRule::QMimeMagicRule(const QString &type,
}
const QByteArray &tempMask = QByteArray::fromHex(QByteArray::fromRawData(
m_mask.constData() + 2, m_mask.size() - 2));
- if (tempMask.size() != m_pattern.size()) {
+ if (Q_UNLIKELY(tempMask.size() != m_pattern.size())) {
m_type = Invalid;
if (errorString)
*errorString = QLatin1String("Invalid magic rule mask size \"") + QLatin1String(m_mask) + QLatin1Char('"');
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index c2add4aeef..c961c25c07 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -559,7 +559,7 @@ QList<QMimeType> QMimeBinaryProvider::allMimeTypes()
void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
{
#ifdef QT_NO_XMLSTREAMREADER
- qWarning() << "Cannot load mime type since QXmlStreamReader is not available.";
+ qWarning("Cannot load mime type since QXmlStreamReader is not available.");
return;
#else
if (data.loaded)
diff --git a/src/corelib/mimetypes/qmimetypeparser.cpp b/src/corelib/mimetypes/qmimetypeparser.cpp
index 9ed345d37e..63e8f14018 100644
--- a/src/corelib/mimetypes/qmimetypeparser.cpp
+++ b/src/corelib/mimetypes/qmimetypeparser.cpp
@@ -164,7 +164,7 @@ bool QMimeTypeParserBase::parseNumber(const QStringRef &n, int *target, QString
{
bool ok;
*target = n.toInt(&ok);
- if (!ok) {
+ if (Q_UNLIKELY(!ok)) {
*errorMessage = QLatin1String("Not a number '") + n + QLatin1String("'.");
return false;
}
@@ -325,7 +325,7 @@ bool QMimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString
}
}
- if (reader.hasError()) {
+ if (Q_UNLIKELY(reader.hasError())) {
if (errorMessage)
*errorMessage = QString::fromLatin1("An error has been encountered at line %1 of %2: %3:").arg(reader.lineNumber()).arg(fileName, reader.errorString());
return false;
diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp
index 117da2e30b..5665bf74f6 100644
--- a/src/corelib/thread/qreadwritelock.cpp
+++ b/src/corelib/thread/qreadwritelock.cpp
@@ -2,6 +2,7 @@
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -45,11 +46,36 @@
#include "qmutex.h"
#include "qthread.h"
#include "qwaitcondition.h"
-
#include "qreadwritelock_p.h"
+#include "qelapsedtimer.h"
+#include "private/qfreelist_p.h"
QT_BEGIN_NAMESPACE
+/*
+ * Implementation details of QReadWriteLock:
+ *
+ * Depending on the valued of d_ptr, the lock is in the following state:
+ * - when d_ptr == 0x0: Unlocked (no readers, no writers) and non-recursive.
+ * - when d_ptr & 0x1: If the least significant bit is set, we are locked for read.
+ * In that case, d_ptr>>4 represents the number of reading threads minus 1. No writers
+ * are waiting, and the lock is not recursive.
+ * - when d_ptr == 0x2: We are locked for write and nobody is waiting. (no contention)
+ * - In any other case, d_ptr points to an actual QReadWriteLockPrivate.
+ */
+
+namespace {
+enum {
+ StateMask = 0x3,
+ StateLockedForRead = 0x1,
+ StateLockedForWrite = 0x2,
+};
+const auto dummyLockedForRead = reinterpret_cast<QReadWriteLockPrivate *>(quintptr(StateLockedForRead));
+const auto dummyLockedForWrite = reinterpret_cast<QReadWriteLockPrivate *>(quintptr(StateLockedForWrite));
+inline bool isUncontendedLocked(const QReadWriteLockPrivate *d)
+{ return quintptr(d) & StateMask; }
+}
+
/*! \class QReadWriteLock
\inmodule QtCore
\brief The QReadWriteLock class provides read-write locking.
@@ -116,8 +142,10 @@ QT_BEGIN_NAMESPACE
\sa lockForRead(), lockForWrite(), RecursionMode
*/
QReadWriteLock::QReadWriteLock(RecursionMode recursionMode)
- : d(new QReadWriteLockPrivate(recursionMode))
-{ }
+ : d_ptr(recursionMode == Recursive ? new QReadWriteLockPrivate(true) : nullptr)
+{
+ Q_ASSERT_X(!(quintptr(d_ptr.load()) & StateMask), "QReadWriteLock::QReadWriteLock", "bad d_ptr alignment");
+}
/*!
Destroys the QReadWriteLock object.
@@ -127,6 +155,11 @@ QReadWriteLock::QReadWriteLock(RecursionMode recursionMode)
*/
QReadWriteLock::~QReadWriteLock()
{
+ auto d = d_ptr.load();
+ if (isUncontendedLocked(d)) {
+ qWarning("QReadWriteLock: destroying locked QReadWriteLock");
+ return;
+ }
delete d;
}
@@ -141,32 +174,9 @@ QReadWriteLock::~QReadWriteLock()
*/
void QReadWriteLock::lockForRead()
{
- QMutexLocker lock(&d->mutex);
-
- Qt::HANDLE self = 0;
- if (d->recursive) {
- self = QThread::currentThreadId();
-
- QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
- if (it != d->currentReaders.end()) {
- ++it.value();
- ++d->accessCount;
- Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::lockForRead()",
- "Overflow in lock counter");
- return;
- }
- }
-
- while (d->accessCount < 0 || d->waitingWriters) {
- ++d->waitingReaders;
- d->readerWait.wait(&d->mutex);
- --d->waitingReaders;
- }
- if (d->recursive)
- d->currentReaders.insert(self, 1);
-
- ++d->accessCount;
- Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::lockForRead()", "Overflow in lock counter");
+ if (d_ptr.testAndSetAcquire(nullptr, dummyLockedForRead))
+ return;
+ tryLockForRead(-1);
}
/*!
@@ -187,31 +197,7 @@ void QReadWriteLock::lockForRead()
*/
bool QReadWriteLock::tryLockForRead()
{
- QMutexLocker lock(&d->mutex);
-
- Qt::HANDLE self = 0;
- if (d->recursive) {
- self = QThread::currentThreadId();
-
- QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
- if (it != d->currentReaders.end()) {
- ++it.value();
- ++d->accessCount;
- Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()",
- "Overflow in lock counter");
- return true;
- }
- }
-
- if (d->accessCount < 0)
- return false;
- if (d->recursive)
- d->currentReaders.insert(self, 1);
-
- ++d->accessCount;
- Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()", "Overflow in lock counter");
-
- return true;
+ return tryLockForRead(0);
}
/*! \overload
@@ -235,36 +221,58 @@ bool QReadWriteLock::tryLockForRead()
*/
bool QReadWriteLock::tryLockForRead(int timeout)
{
- QMutexLocker lock(&d->mutex);
-
- Qt::HANDLE self = 0;
- if (d->recursive) {
- self = QThread::currentThreadId();
+ // Fast case: non contended:
+ QReadWriteLockPrivate *d;
+ if (d_ptr.testAndSetAcquire(nullptr, dummyLockedForRead, d))
+ return true;
+
+ while (true) {
+ if (d == 0) {
+ if (!d_ptr.testAndSetAcquire(nullptr, dummyLockedForRead, d))
+ continue;
+ return true;
+ }
- QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
- if (it != d->currentReaders.end()) {
- ++it.value();
- ++d->accessCount;
- Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()",
+ if ((quintptr(d) & StateMask) == StateLockedForRead) {
+ // locked for read, increase the counter
+ const auto val = reinterpret_cast<QReadWriteLockPrivate *>(quintptr(d) + (1U<<4));
+ Q_ASSERT_X(quintptr(val) > (1U<<4), "QReadWriteLock::tryLockForRead()",
"Overflow in lock counter");
+ if (!d_ptr.testAndSetAcquire(d, val, d))
+ continue;
return true;
}
- }
- while (d->accessCount < 0 || d->waitingWriters) {
- ++d->waitingReaders;
- bool success = d->readerWait.wait(&d->mutex, timeout < 0 ? ULONG_MAX : ulong(timeout));
- --d->waitingReaders;
- if (!success)
- return false;
+ if (d == dummyLockedForWrite) {
+ // locked for write, assign a d_ptr and wait.
+ auto val = QReadWriteLockPrivate::allocate();
+ val->writerCount = 1;
+ if (!d_ptr.testAndSetOrdered(d, val, d)) {
+ val->writerCount = 0;
+ val->release();
+ continue;
+ }
+ d = val;
+ }
+ Q_ASSERT(!isUncontendedLocked(d));
+ // d is an actual pointer;
+
+ if (d->recursive)
+ return d->recursiveLockForRead(timeout);
+
+ QMutexLocker lock(&d->mutex);
+ if (d != d_ptr.load()) {
+ // d_ptr has changed: this QReadWriteLock was unlocked before we had
+ // time to lock d->mutex.
+ // We are holding a lock to a mutex within a QReadWriteLockPrivate
+ // that is already released (or even is already re-used). That's ok
+ // because the QFreeList never frees them.
+ // Just unlock d->mutex (at the end of the scope) and retry.
+ d = d_ptr.loadAcquire();
+ continue;
+ }
+ return d->lockForRead(timeout);
}
- if (d->recursive)
- d->currentReaders.insert(self, 1);
-
- ++d->accessCount;
- Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()", "Overflow in lock counter");
-
- return true;
}
/*!
@@ -280,30 +288,7 @@ bool QReadWriteLock::tryLockForRead(int timeout)
*/
void QReadWriteLock::lockForWrite()
{
- QMutexLocker lock(&d->mutex);
-
- Qt::HANDLE self = 0;
- if (d->recursive) {
- self = QThread::currentThreadId();
-
- if (d->currentWriter == self) {
- --d->accessCount;
- Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::lockForWrite()",
- "Overflow in lock counter");
- return;
- }
- }
-
- while (d->accessCount != 0) {
- ++d->waitingWriters;
- d->writerWait.wait(&d->mutex);
- --d->waitingWriters;
- }
- if (d->recursive)
- d->currentWriter = self;
-
- --d->accessCount;
- Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::lockForWrite()", "Overflow in lock counter");
+ tryLockForWrite(-1);
}
/*!
@@ -323,30 +308,7 @@ void QReadWriteLock::lockForWrite()
*/
bool QReadWriteLock::tryLockForWrite()
{
- QMutexLocker lock(&d->mutex);
-
- Qt::HANDLE self = 0;
- if (d->recursive) {
- self = QThread::currentThreadId();
-
- if (d->currentWriter == self) {
- --d->accessCount;
- Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::lockForWrite()",
- "Overflow in lock counter");
- return true;
- }
- }
-
- if (d->accessCount != 0)
- return false;
- if (d->recursive)
- d->currentWriter = self;
-
- --d->accessCount;
- Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::tryLockForWrite()",
- "Overflow in lock counter");
-
- return true;
+ return tryLockForWrite(0);
}
/*! \overload
@@ -370,36 +332,48 @@ bool QReadWriteLock::tryLockForWrite()
*/
bool QReadWriteLock::tryLockForWrite(int timeout)
{
- QMutexLocker lock(&d->mutex);
-
- Qt::HANDLE self = 0;
- if (d->recursive) {
- self = QThread::currentThreadId();
-
- if (d->currentWriter == self) {
- --d->accessCount;
- Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::lockForWrite()",
- "Overflow in lock counter");
+ // Fast case: non contended:
+ QReadWriteLockPrivate *d;
+ if (d_ptr.testAndSetAcquire(nullptr, dummyLockedForWrite, d))
+ return true;
+
+ while (true) {
+ if (d == 0) {
+ if (!d_ptr.testAndSetAcquire(d, dummyLockedForWrite, d))
+ continue;
return true;
}
- }
-
- while (d->accessCount != 0) {
- ++d->waitingWriters;
- bool success = d->writerWait.wait(&d->mutex, timeout < 0 ? ULONG_MAX : ulong(timeout));
- --d->waitingWriters;
- if (!success)
- return false;
+ if (isUncontendedLocked(d)) {
+ // locked for either read or write, assign a d_ptr and wait.
+ auto val = QReadWriteLockPrivate::allocate();
+ if (d == dummyLockedForWrite)
+ val->writerCount = 1;
+ else
+ val->readerCount = (quintptr(d) >> 4) + 1;
+ if (!d_ptr.testAndSetOrdered(d, val, d)) {
+ val->writerCount = val->readerCount = 0;
+ val->release();
+ continue;
+ }
+ d = val;
+ }
+ Q_ASSERT(!isUncontendedLocked(d));
+ // d is an actual pointer;
+
+ if (d->recursive)
+ return d->recursiveLockForWrite(timeout);
+
+ QMutexLocker lock(&d->mutex);
+ if (d != d_ptr.load()) {
+ // The mutex was unlocked before we had time to lock the mutex.
+ // We are holding to a mutex within a QReadWriteLockPrivate that is already released
+ // (or even is already re-used) but that's ok because the QFreeList never frees them.
+ d = d_ptr.loadAcquire();
+ continue;
+ }
+ return d->lockForWrite(timeout);
}
- if (d->recursive)
- d->currentWriter = self;
-
- --d->accessCount;
- Q_ASSERT_X(d->accessCount < 0, "QReadWriteLock::tryLockForWrite()",
- "Overflow in lock counter");
-
- return true;
}
/*!
@@ -412,36 +386,246 @@ bool QReadWriteLock::tryLockForWrite(int timeout)
*/
void QReadWriteLock::unlock()
{
- QMutexLocker lock(&d->mutex);
+ QReadWriteLockPrivate *d = d_ptr.load();
+ while (true) {
+ Q_ASSERT_X(d, "QReadWriteLock::unlock()", "Cannot unlock an unlocked lock");
+
+ // Fast case: no contention: (no waiters, no other readers)
+ if (quintptr(d) <= 2) { // 1 or 2 (StateLockedForRead or StateLockedForWrite)
+ if (!d_ptr.testAndSetRelease(d, nullptr, d))
+ continue;
+ return;
+ }
- Q_ASSERT_X(d->accessCount != 0, "QReadWriteLock::unlock()", "Cannot unlock an unlocked lock");
+ if ((quintptr(d) & StateMask) == StateLockedForRead) {
+ Q_ASSERT(quintptr(d) > (1U<<4)); //otherwise that would be the fast case
+ // Just decrease the reader's count.
+ auto val = reinterpret_cast<QReadWriteLockPrivate *>(quintptr(d) - (1U<<4));
+ if (!d_ptr.testAndSetRelease(d, val, d))
+ continue;
+ return;
+ }
+
+ Q_ASSERT(!isUncontendedLocked(d));
- bool unlocked = false;
- if (d->accessCount > 0) {
- // releasing a read lock
if (d->recursive) {
- Qt::HANDLE self = QThread::currentThreadId();
- QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self);
- if (it != d->currentReaders.end()) {
- if (--it.value() <= 0)
- d->currentReaders.erase(it);
+ d->recursiveUnlock();
+ return;
+ }
+
+ QMutexLocker locker(&d->mutex);
+ if (d->writerCount) {
+ Q_ASSERT(d->writerCount == 1);
+ Q_ASSERT(d->readerCount == 0);
+ d->writerCount = 0;
+ } else {
+ Q_ASSERT(d->readerCount > 0);
+ d->readerCount--;
+ if (d->readerCount > 0)
+ return;
+ }
+
+ if (d->waitingReaders || d->waitingWriters) {
+ d->unlock();
+ } else {
+ Q_ASSERT(d_ptr.load() == d); // should not change when we still hold the mutex
+ d_ptr.storeRelease(nullptr);
+ d->release();
+ }
+ return;
+ }
+}
+
+/*! \internal Helper for QWaitCondition::wait */
+QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() const
+{
+ QReadWriteLockPrivate *d = d_ptr.load();
+ switch (quintptr(d) & StateMask) {
+ case StateLockedForRead: return LockedForRead;
+ case StateLockedForWrite: return LockedForWrite;
+ }
+
+ if (!d)
+ return Unlocked;
+ if (d->writerCount > 1)
+ return RecursivelyLocked;
+ else if (d->writerCount == 1)
+ return LockedForWrite;
+ return LockedForRead;
+
+}
+
+bool QReadWriteLockPrivate::lockForRead(int timeout)
+{
+ Q_ASSERT(!mutex.tryLock()); // mutex must be locked when entering this function
+
+ QElapsedTimer t;
+ if (timeout > 0)
+ t.start();
+
+ while (waitingWriters || writerCount) {
+ if (timeout == 0)
+ return false;
+ if (timeout > 0) {
+ auto elapsed = t.elapsed();
+ if (elapsed > timeout)
+ return false;
+ waitingReaders++;
+ readerCond.wait(&mutex, timeout - elapsed);
+ } else {
+ waitingReaders++;
+ readerCond.wait(&mutex);
+ }
+ waitingReaders--;
+ }
+ readerCount++;
+ Q_ASSERT(writerCount == 0);
+ return true;
+}
+
+bool QReadWriteLockPrivate::lockForWrite(int timeout)
+{
+ Q_ASSERT(!mutex.tryLock()); // mutex must be locked when entering this function
+
+ QElapsedTimer t;
+ if (timeout > 0)
+ t.start();
+
+ while (readerCount || writerCount) {
+ if (timeout == 0)
+ return false;
+ if (timeout > 0) {
+ auto elapsed = t.elapsed();
+ if (elapsed > timeout) {
+ if (waitingReaders && !waitingWriters && !writerCount) {
+ // We timed out and now there is no more writers or waiting writers, but some
+ // readers were queueud (probably because of us). Wake the waiting readers.
+ readerCond.wakeAll();
+ }
+ return false;
}
+ waitingWriters++;
+ writerCond.wait(&mutex, timeout - elapsed);
+ } else {
+ waitingWriters++;
+ writerCond.wait(&mutex);
}
+ waitingWriters--;
+ }
+
+ Q_ASSERT(writerCount == 0);
+ Q_ASSERT(readerCount == 0);
+ writerCount = 1;
+ return true;
+}
+
+void QReadWriteLockPrivate::unlock()
+{
+ Q_ASSERT(!mutex.tryLock()); // mutex must be locked when entering this function
+ if (waitingWriters)
+ writerCond.wakeOne();
+ else if (waitingReaders)
+ readerCond.wakeAll();
+}
+
+bool QReadWriteLockPrivate::recursiveLockForRead(int timeout)
+{
+ Q_ASSERT(recursive);
+ QMutexLocker lock(&mutex);
+
+ Qt::HANDLE self = QThread::currentThreadId();
+
+ auto it = currentReaders.find(self);
+ if (it != currentReaders.end()) {
+ ++it.value();
+ return true;
+ }
- unlocked = --d->accessCount == 0;
- } else if (d->accessCount < 0 && ++d->accessCount == 0) {
- // released a write lock
- unlocked = true;
- d->currentWriter = 0;
+ if (!lockForRead(timeout))
+ return false;
+
+ currentReaders.insert(self, 1);
+ return true;
+}
+
+bool QReadWriteLockPrivate::recursiveLockForWrite(int timeout)
+{
+ Q_ASSERT(recursive);
+ QMutexLocker lock(&mutex);
+
+ Qt::HANDLE self = QThread::currentThreadId();
+ if (currentWriter == self) {
+ writerCount++;
+ return true;
}
- if (unlocked) {
- if (d->waitingWriters) {
- d->writerWait.wakeOne();
- } else if (d->waitingReaders) {
- d->readerWait.wakeAll();
+ if (!lockForWrite(timeout))
+ return false;
+
+ currentWriter = self;
+ return true;
+}
+
+void QReadWriteLockPrivate::recursiveUnlock()
+{
+ Q_ASSERT(recursive);
+ QMutexLocker lock(&mutex);
+
+ Qt::HANDLE self = QThread::currentThreadId();
+ if (self == currentWriter) {
+ if (--writerCount > 0)
+ return;
+ currentWriter = 0;
+ } else {
+ auto it = currentReaders.find(self);
+ if (it == currentReaders.end()) {
+ qWarning("QReadWriteLock::unlock: unlocking from a thread that did not lock");
+ return;
+ } else {
+ if (--it.value() <= 0) {
+ currentReaders.erase(it);
+ readerCount--;
+ }
+ if (readerCount)
+ return;
}
}
+
+ unlock();
+}
+
+// The freelist management
+namespace {
+struct FreeListConstants : QFreeListDefaultConstants {
+ enum { BlockCount = 4, MaxIndex=0xffff };
+ static const int Sizes[BlockCount];
+};
+const int FreeListConstants::Sizes[FreeListConstants::BlockCount] = {
+ 16,
+ 128,
+ 1024,
+ FreeListConstants::MaxIndex - (16 + 128 + 1024)
+};
+
+typedef QFreeList<QReadWriteLockPrivate, FreeListConstants> FreeList;
+Q_GLOBAL_STATIC(FreeList, freelist);
+}
+
+QReadWriteLockPrivate *QReadWriteLockPrivate::allocate()
+{
+ int i = freelist->next();
+ QReadWriteLockPrivate *d = &(*freelist)[i];
+ d->id = i;
+ Q_ASSERT(!d->recursive);
+ Q_ASSERT(!d->waitingReaders && !d->waitingReaders && !d->readerCount && !d->writerCount);
+ return d;
+}
+
+void QReadWriteLockPrivate::release()
+{
+ Q_ASSERT(!recursive);
+ Q_ASSERT(!waitingReaders && !waitingReaders && !readerCount && !writerCount);
+ freelist->release(id);
}
/*!
diff --git a/src/corelib/thread/qreadwritelock.h b/src/corelib/thread/qreadwritelock.h
index b7e2092e38..777efdb3bf 100644
--- a/src/corelib/thread/qreadwritelock.h
+++ b/src/corelib/thread/qreadwritelock.h
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_THREAD
-struct QReadWriteLockPrivate;
+class QReadWriteLockPrivate;
class Q_CORE_EXPORT QReadWriteLock
{
@@ -69,8 +69,10 @@ public:
private:
Q_DISABLE_COPY(QReadWriteLock)
- QReadWriteLockPrivate *d;
+ QAtomicPointer<QReadWriteLockPrivate> d_ptr;
+ enum StateForWaitCondition { LockedForRead, LockedForWrite, Unlocked, RecursivelyLocked };
+ StateForWaitCondition stateForWaitCondition() const;
friend class QWaitCondition;
};
diff --git a/src/corelib/thread/qreadwritelock_p.h b/src/corelib/thread/qreadwritelock_p.h
index 1f6f73c8e3..285f017655 100644
--- a/src/corelib/thread/qreadwritelock_p.h
+++ b/src/corelib/thread/qreadwritelock_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -53,29 +54,47 @@
#include <QtCore/qglobal.h>
#include <QtCore/qhash.h>
+#include <QtCore/QWaitCondition>
#ifndef QT_NO_THREAD
QT_BEGIN_NAMESPACE
-struct QReadWriteLockPrivate
+class QReadWriteLockPrivate
{
- QReadWriteLockPrivate(QReadWriteLock::RecursionMode recursionMode)
- : accessCount(0), waitingReaders(0), waitingWriters(0),
- recursive(recursionMode == QReadWriteLock::Recursive), currentWriter(0)
- { }
+public:
+ QReadWriteLockPrivate(bool isRecursive = false)
+ : readerCount(0), writerCount(0), waitingReaders(0), waitingWriters(0),
+ recursive(isRecursive), id(0) {}
QMutex mutex;
- QWaitCondition readerWait;
- QWaitCondition writerWait;
-
- int accessCount;
+ QWaitCondition writerCond;
+ QWaitCondition readerCond;
+ int readerCount;
+ int writerCount;
int waitingReaders;
int waitingWriters;
-
bool recursive;
+
+ //Called with the mutex locked
+ bool lockForWrite(int timeout);
+ bool lockForRead(int timeout);
+ void unlock();
+
+ //memory management
+ int id;
+ void release();
+ static QReadWriteLockPrivate *allocate();
+
+ // Recusive mutex handling
Qt::HANDLE currentWriter;
QHash<Qt::HANDLE, int> currentReaders;
+
+ // called with the mutex unlocked
+ bool recursiveLockForWrite(int timeout);
+ bool recursiveLockForRead(int timeout);
+ void recursiveUnlock();
+
};
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qwaitcondition_unix.cpp b/src/corelib/thread/qwaitcondition_unix.cpp
index 2a98fd2897..6adee5412e 100644
--- a/src/corelib/thread/qwaitcondition_unix.cpp
+++ b/src/corelib/thread/qwaitcondition_unix.cpp
@@ -221,9 +221,12 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
{
- if (!readWriteLock || readWriteLock->d->accessCount == 0)
+ if (!readWriteLock)
return false;
- if (readWriteLock->d->accessCount < -1) {
+ auto previousState = readWriteLock->stateForWaitCondition();
+ if (previousState == QReadWriteLock::Unlocked)
+ return false;
+ if (previousState == QReadWriteLock::RecursivelyLocked) {
qWarning("QWaitCondition: cannot wait on QReadWriteLocks with recursive lockForWrite()");
return false;
}
@@ -231,12 +234,11 @@ bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
report_error(pthread_mutex_lock(&d->mutex), "QWaitCondition::wait()", "mutex lock");
++d->waiters;
- int previousAccessCount = readWriteLock->d->accessCount;
readWriteLock->unlock();
bool returnValue = d->wait(time);
- if (previousAccessCount < 0)
+ if (previousState == QReadWriteLock::LockedForWrite)
readWriteLock->lockForWrite();
else
readWriteLock->lockForRead();
diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp
index 246e45a54c..f3a645c504 100644
--- a/src/corelib/thread/qwaitcondition_win.cpp
+++ b/src/corelib/thread/qwaitcondition_win.cpp
@@ -191,20 +191,22 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
{
- if (!readWriteLock || readWriteLock->d->accessCount == 0)
+ if (!readWriteLock)
return false;
- if (readWriteLock->d->accessCount < -1) {
+ auto previousState = readWriteLock->stateForWaitCondition();
+ if (previousState == QReadWriteLock::Unlocked)
+ return false;
+ if (previousState == QReadWriteLock::RecursivelyLocked) {
qWarning("QWaitCondition: cannot wait on QReadWriteLocks with recursive lockForWrite()");
return false;
}
QWaitConditionEvent *wce = d->pre();
- int previousAccessCount = readWriteLock->d->accessCount;
readWriteLock->unlock();
bool returnValue = d->wait(wce, time);
- if (previousAccessCount < 0)
+ if (previousState == QReadWriteLock::LockedForWrite)
readWriteLock->lockForWrite();
else
readWriteLock->lockForRead();
diff --git a/src/corelib/tools/qcollator_macx.cpp b/src/corelib/tools/qcollator_macx.cpp
index 207b5bb2b1..b4d93e58d4 100644
--- a/src/corelib/tools/qcollator_macx.cpp
+++ b/src/corelib/tools/qcollator_macx.cpp
@@ -55,7 +55,7 @@ void QCollatorPrivate::init()
LocaleRef localeRef;
int rc = LocaleRefFromLocaleString(locale.bcp47Name().toLocal8Bit(), &localeRef);
if (rc != 0)
- qWarning() << "couldn't initialize the locale";
+ qWarning("couldn't initialize the locale");
UInt32 options = 0;
@@ -73,7 +73,7 @@ void QCollatorPrivate::init()
&collator
);
if (status != 0)
- qWarning() << "Couldn't initialize the collator";
+ qWarning("Couldn't initialize the collator");
dirty = false;
}
diff --git a/src/corelib/tools/qcollator_win.cpp b/src/corelib/tools/qcollator_win.cpp
index 30e358c3f9..fcd8d069eb 100644
--- a/src/corelib/tools/qcollator_win.cpp
+++ b/src/corelib/tools/qcollator_win.cpp
@@ -73,7 +73,7 @@ void QCollatorPrivate::init()
if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7)
collator |= SORT_DIGITSASNUMBERS;
else
- qWarning() << "Numeric sorting unsupported on Windows versions older than Windows 7.";
+ qWarning("Numeric sorting unsupported on Windows versions older than Windows 7.");
}
if (ignorePunctuation)
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index 7eec281957..9801878bdc 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -909,7 +909,7 @@ template <class Key, class T>
void QMap<Key, T>::dump() const
{
const_iterator it = begin();
- qDebug() << "map dump:";
+ qDebug("map dump:");
while (it != end()) {
const QMapNodeBase *n = it.i;
int depth = 0;
@@ -922,7 +922,7 @@ void QMap<Key, T>::dump() const
<< it.key() << it.value();
++it;
}
- qDebug() << "---------";
+ qDebug("---------");
}
#endif
diff --git a/src/corelib/tools/qtimeline.cpp b/src/corelib/tools/qtimeline.cpp
index dd6a4dbc56..adbc2900e3 100644
--- a/src/corelib/tools/qtimeline.cpp
+++ b/src/corelib/tools/qtimeline.cpp
@@ -131,7 +131,7 @@ void QTimeLinePrivate::setCurrentTime(int msecs)
const int transitionframe = (direction == QTimeLine::Forward ? endFrame : startFrame);
if (looping && !finished && transitionframe != currentFrame) {
#ifdef QTIMELINE_DEBUG
- qDebug() << "QTimeLinePrivate::setCurrentTime: transitionframe";
+ qDebug("QTimeLinePrivate::setCurrentTime: transitionframe");
#endif
emit q->frameChanged(transitionframe, QTimeLine::QPrivateSignal());
}