diff options
author | Liang Qi <liang.qi@qt.io> | 2017-02-14 11:33:02 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-02-14 11:33:02 +0100 |
commit | 27432d40f2500b11780398f6c7d67719050dae6c (patch) | |
tree | 97f9a60af2d520d66fa7ff802ccddad56e0cadaf /src/corelib | |
parent | 071a120400b17eaa0b414a0ed262b0a090908679 (diff) | |
parent | 10ecbc4041cb7db004f4ed4d40ce082553d75844 (diff) |
Merge remote-tracking branch 'origin/5.8' into 5.9
Change-Id: I2bd2e61bae1eab4fc74fa6accd741ed9ae1f0669
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/global/qconfig-bootstrapped.h | 1 | ||||
-rw-r--r-- | src/corelib/global/qglobal.cpp | 5 | ||||
-rw-r--r-- | src/corelib/io/qiodevice.cpp | 159 | ||||
-rw-r--r-- | src/corelib/io/qiodevice_p.h | 1 | ||||
-rw-r--r-- | src/corelib/io/qresource.cpp | 22 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 17 | ||||
-rw-r--r-- | src/corelib/plugin/qlibrary.cpp | 34 | ||||
-rw-r--r-- | src/corelib/thread/qthread_win.cpp | 4 | ||||
-rw-r--r-- | src/corelib/tools/qsimd_p.h | 32 | ||||
-rw-r--r-- | src/corelib/tools/qvector.qdoc (renamed from src/corelib/tools/qvector.cpp) | 0 | ||||
-rw-r--r-- | src/corelib/tools/tools.pri | 1 |
11 files changed, 160 insertions, 116 deletions
diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h index d7849d4699..1c806e0774 100644 --- a/src/corelib/global/qconfig-bootstrapped.h +++ b/src/corelib/global/qconfig-bootstrapped.h @@ -77,6 +77,7 @@ #define QT_NO_SYSTEMLOCALE #define QT_FEATURE_slog2 -1 #define QT_FEATURE_syslog -1 +#define QT_FEATURE_temporaryfile 1 #define QT_NO_THREAD #define QT_FEATURE_timezone -1 #define QT_FEATURE_topleveldomain -1 diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 153d7466ed..f8c58c6b3e 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -3974,7 +3974,10 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) { Q_ASSERT_X(cb >= 0, "QInternal::activateCallback()", "Callback id must be a valid id"); - QInternal_CallBackTable *cbt = global_callback_table(); + if (!global_callback_table.exists()) + return false; + + QInternal_CallBackTable *cbt = &(*global_callback_table); if (cbt && cb < cbt->callbacks.size()) { QList<qInternalCallback> callbacks = cbt->callbacks[cb]; bool ret = false; diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 52a78ad1c4..41a4d7a1ba 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -1007,10 +1007,9 @@ qint64 QIODevice::read(char *data, qint64 maxSize) #endif const bool sequential = d->isSequential(); - const bool keepDataInBuffer = sequential && d->transactionStarted; - // Short circuit for getChar() - if (maxSize == 1 && !keepDataInBuffer) { + // Short-cut for getChar(), unless we need to keep the data in the buffer. + if (maxSize == 1 && !(sequential && d->transactionStarted)) { int chint; while ((chint = d->buffer.getChar()) != -1) { if (!sequential) @@ -1031,43 +1030,67 @@ qint64 QIODevice::read(char *data, qint64 maxSize) } CHECK_MAXLEN(read, qint64(-1)); + CHECK_READABLE(read, qint64(-1)); + + const qint64 readBytes = d->read(data, maxSize); + +#if defined QIODEVICE_DEBUG + printf("%p \treturning %lld, d->pos == %lld, d->buffer.size() == %lld\n", this, + readBytes, d->pos, d->buffer.size()); + if (readBytes > 0) + debugBinaryString(data - readBytes, readBytes); +#endif + + return readBytes; +} + +/*! + \internal +*/ +qint64 QIODevicePrivate::read(char *data, qint64 maxSize, bool peeking) +{ + Q_Q(QIODevice); + + const bool buffered = (openMode & QIODevice::Unbuffered) == 0; + const bool sequential = isSequential(); + const bool keepDataInBuffer = sequential + ? peeking || transactionStarted + : peeking && buffered; + const qint64 savedPos = pos; qint64 readSoFar = 0; bool madeBufferReadsOnly = true; bool deviceAtEof = false; char *readPtr = data; + qint64 bufferPos = (sequential && transactionStarted) ? transactionPos : Q_INT64_C(0); forever { // Try reading from the buffer. qint64 bufferReadChunkSize = keepDataInBuffer - ? d->buffer.peek(data, maxSize, d->transactionPos) - : d->buffer.read(data, maxSize); + ? buffer.peek(data, maxSize, bufferPos) + : buffer.read(data, maxSize); if (bufferReadChunkSize > 0) { - if (keepDataInBuffer) - d->transactionPos += bufferReadChunkSize; - else if (!sequential) - d->pos += bufferReadChunkSize; + bufferPos += bufferReadChunkSize; + if (!sequential) + pos += bufferReadChunkSize; +#if defined QIODEVICE_DEBUG + printf("%p \treading %lld bytes from buffer into position %lld\n", q, + bufferReadChunkSize, readSoFar); +#endif readSoFar += bufferReadChunkSize; data += bufferReadChunkSize; maxSize -= bufferReadChunkSize; -#if defined QIODEVICE_DEBUG - printf("%p \treading %lld bytes from buffer into position %lld\n", this, - bufferReadChunkSize, readSoFar - bufferReadChunkSize); -#endif - } else { - CHECK_READABLE(read, qint64(-1)); } if (maxSize > 0 && !deviceAtEof) { qint64 readFromDevice = 0; // Make sure the device is positioned correctly. - if (sequential || d->pos == d->devicePos || seek(d->pos)) { + if (sequential || pos == devicePos || q->seek(pos)) { madeBufferReadsOnly = false; // fix readData attempt - if ((maxSize >= d->readBufferChunkSize || (d->openMode & Unbuffered)) - && !keepDataInBuffer) { + if ((!buffered || maxSize >= readBufferChunkSize) && !keepDataInBuffer) { // Read big chunk directly to output buffer - readFromDevice = readData(data, maxSize); + readFromDevice = q->readData(data, maxSize); deviceAtEof = (readFromDevice != maxSize); #if defined QIODEVICE_DEBUG - printf("%p \treading %lld bytes from device (total %lld)\n", this, + printf("%p \treading %lld bytes from device (total %lld)\n", q, readFromDevice, readSoFar); #endif if (readFromDevice > 0) { @@ -1075,24 +1098,24 @@ qint64 QIODevice::read(char *data, qint64 maxSize) data += readFromDevice; maxSize -= readFromDevice; if (!sequential) { - d->pos += readFromDevice; - d->devicePos += readFromDevice; + pos += readFromDevice; + devicePos += readFromDevice; } } } else { // Do not read more than maxSize on unbuffered devices - const qint64 bytesToBuffer = (d->openMode & Unbuffered) - ? qMin(maxSize, qint64(d->readBufferChunkSize)) - : qint64(d->readBufferChunkSize); + const qint64 bytesToBuffer = (buffered || readBufferChunkSize < maxSize) + ? qint64(readBufferChunkSize) + : maxSize; // Try to fill QIODevice buffer by single read - readFromDevice = readData(d->buffer.reserve(bytesToBuffer), bytesToBuffer); + readFromDevice = q->readData(buffer.reserve(bytesToBuffer), bytesToBuffer); deviceAtEof = (readFromDevice != bytesToBuffer); - d->buffer.chop(bytesToBuffer - qMax(Q_INT64_C(0), readFromDevice)); + buffer.chop(bytesToBuffer - qMax(Q_INT64_C(0), readFromDevice)); if (readFromDevice > 0) { if (!sequential) - d->devicePos += readFromDevice; + devicePos += readFromDevice; #if defined QIODEVICE_DEBUG - printf("%p \treading %lld from device into buffer\n", this, + printf("%p \treading %lld from device into buffer\n", q, readFromDevice); #endif continue; @@ -1108,7 +1131,7 @@ qint64 QIODevice::read(char *data, qint64 maxSize) } } - if ((d->openMode & Text) && readPtr < data) { + if ((openMode & QIODevice::Text) && readPtr < data) { const char *endPtr = data; // optimization to avoid initial self-assignment @@ -1140,14 +1163,18 @@ qint64 QIODevice::read(char *data, qint64 maxSize) break; } -#if defined QIODEVICE_DEBUG - printf("%p \treturning %lld, d->pos == %lld, d->buffer.size() == %lld\n", this, - readSoFar, d->pos, d->buffer.size()); - debugBinaryString(data - readSoFar, readSoFar); -#endif + // Restore positions after reading + if (keepDataInBuffer) { + if (peeking) + pos = savedPos; // does nothing on sequential devices + else + transactionPos = bufferPos; + } else if (peeking) { + seekBuffer(savedPos); // unbuffered random-access device + } - if (madeBufferReadsOnly && d->isBufferEmpty()) - readData(data, 0); + if (madeBufferReadsOnly && isBufferEmpty()) + q->readData(data, 0); return readSoFar; } @@ -1759,27 +1786,7 @@ bool QIODevicePrivate::putCharHelper(char c) */ qint64 QIODevicePrivate::peek(char *data, qint64 maxSize) { - Q_Q(QIODevice); - - if (transactionStarted) { - const qint64 savedTransactionPos = transactionPos; - const qint64 savedPos = pos; - - qint64 readBytes = q->read(data, maxSize); - - // Restore initial position - if (isSequential()) - transactionPos = savedTransactionPos; - else - seekBuffer(savedPos); - return readBytes; - } - - q->startTransaction(); - qint64 readBytes = q->read(data, maxSize); - q->rollbackTransaction(); - - return readBytes; + return read(data, maxSize, true); } /*! @@ -1787,26 +1794,17 @@ qint64 QIODevicePrivate::peek(char *data, qint64 maxSize) */ QByteArray QIODevicePrivate::peek(qint64 maxSize) { - Q_Q(QIODevice); - - if (transactionStarted) { - const qint64 savedTransactionPos = transactionPos; - const qint64 savedPos = pos; + QByteArray result(maxSize, Qt::Uninitialized); - QByteArray result = q->read(maxSize); + const qint64 readBytes = read(result.data(), maxSize, true); - // Restore initial position - if (isSequential()) - transactionPos = savedTransactionPos; + if (readBytes < maxSize) { + if (readBytes <= 0) + result.clear(); else - seekBuffer(savedPos); - return result; + result.resize(readBytes); } - q->startTransaction(); - QByteArray result = q->read(maxSize); - q->rollbackTransaction(); - return result; } @@ -1844,7 +1842,12 @@ bool QIODevice::getChar(char *c) */ qint64 QIODevice::peek(char *data, qint64 maxSize) { - return d_func()->peek(data, maxSize); + Q_D(QIODevice); + + CHECK_MAXLEN(peek, qint64(-1)); + CHECK_READABLE(peek, qint64(-1)); + + return d->peek(data, maxSize); } /*! @@ -1866,7 +1869,13 @@ qint64 QIODevice::peek(char *data, qint64 maxSize) */ QByteArray QIODevice::peek(qint64 maxSize) { - return d_func()->peek(maxSize); + Q_D(QIODevice); + + CHECK_MAXLEN(peek, QByteArray()); + CHECK_MAXBYTEARRAYSIZE(peek); + CHECK_READABLE(peek, QByteArray()); + + return d->peek(maxSize); } /*! diff --git a/src/corelib/io/qiodevice_p.h b/src/corelib/io/qiodevice_p.h index 76bec89ef2..71a326dd53 100644 --- a/src/corelib/io/qiodevice_p.h +++ b/src/corelib/io/qiodevice_p.h @@ -171,6 +171,7 @@ public: void setReadChannelCount(int count); void setWriteChannelCount(int count); + qint64 read(char *data, qint64 maxSize, bool peeking = false); virtual qint64 peek(char *data, qint64 maxSize); virtual QByteArray peek(qint64 maxSize); diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index febf22639c..32639759e4 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -149,12 +149,23 @@ static QString cleanPath(const QString &_path) Q_DECLARE_TYPEINFO(QResourceRoot, Q_MOVABLE_TYPE); -Q_GLOBAL_STATIC_WITH_ARGS(QMutex, resourceMutex, (QMutex::Recursive)) - typedef QList<QResourceRoot*> ResourceList; -Q_GLOBAL_STATIC(ResourceList, resourceList) +struct QResourceGlobalData +{ + QMutex resourceMutex{QMutex::Recursive}; + ResourceList resourceList; + QStringList resourceSearchPaths; +}; +Q_GLOBAL_STATIC(QResourceGlobalData, resourceGlobalData) + +static inline QMutex *resourceMutex() +{ return &resourceGlobalData->resourceMutex; } -Q_GLOBAL_STATIC(QStringList, resourceSearchPaths) +static inline ResourceList *resourceList() +{ return &resourceGlobalData->resourceList; } + +static inline QStringList *resourceSearchPaths() +{ return &resourceGlobalData->resourceSearchPaths; } /*! \class QResource @@ -870,6 +881,9 @@ Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree, Q_CORE_EXPORT bool qUnregisterResourceData(int version, const unsigned char *tree, const unsigned char *name, const unsigned char *data) { + if (resourceGlobalData.isDestroyed()) + return false; + QMutexLocker lock(resourceMutex()); if ((version == 0x01 || version == 0x02) && resourceList()) { QResourceRoot res(version, tree, name, data); diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index a936457bce..0ac49c5019 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -305,12 +305,13 @@ void qRemovePostRoutine(QtCleanUpFunction p) static void qt_call_pre_routines() { - QStartUpFuncList *list = preRList(); - if (!list) + if (!preRList.exists()) return; + #ifndef QT_NO_THREAD QMutexLocker locker(&globalPreRoutinesMutex); #endif + QVFuncList *list = &(*preRList); // Unlike qt_call_post_routines, we don't empty the list, because // Q_COREAPP_STARTUP_FUNCTION is a macro, so the user expects // the function to be executed every time QCoreApplication is created. @@ -320,16 +321,10 @@ static void qt_call_pre_routines() void Q_CORE_EXPORT qt_call_post_routines() { - QVFuncList *list = 0; - QT_TRY { - list = postRList(); - } QT_CATCH(const std::bad_alloc &) { - // ignore - if we can't allocate a post routine list, - // there's a high probability that there's no post - // routine to be executed :) - } - if (!list) + if (!postRList.exists()) return; + + QVFuncList *list = &(*postRList); while (!list->isEmpty()) (list->takeFirst())(); } diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index aff2991ed1..96cf5371f9 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -617,40 +617,34 @@ bool QLibrary::isLibrary(const QString &fileName) { #if defined(Q_OS_WIN) return fileName.endsWith(QLatin1String(".dll"), Qt::CaseInsensitive); -#else +#else // Generic Unix QString completeSuffix = QFileInfo(fileName).completeSuffix(); if (completeSuffix.isEmpty()) return false; const QVector<QStringRef> suffixes = completeSuffix.splitRef(QLatin1Char('.')); -# if defined(Q_OS_DARWIN) - - // On Mac, libs look like libmylib.1.0.0.dylib - const QStringRef &lastSuffix = suffixes.at(suffixes.count() - 1); - const QStringRef &firstSuffix = suffixes.at(0); - - bool valid = (lastSuffix == QLatin1String("dylib") - || firstSuffix == QLatin1String("so") - || firstSuffix == QLatin1String("bundle")); - - return valid; -# else // Generic Unix QStringList validSuffixList; -# if defined(Q_OS_HPUX) +# if defined(Q_OS_HPUX) /* See "HP-UX Linker and Libraries User's Guide", section "Link-time Differences between PA-RISC and IPF": "In PA-RISC (PA-32 and PA-64) shared libraries are suffixed with .sl. In IPF (32-bit and 64-bit), the shared libraries are suffixed with .so. For compatibility, the IPF linker also supports the .sl suffix." */ validSuffixList << QLatin1String("sl"); -# if defined __ia64 +# if defined __ia64 validSuffixList << QLatin1String("so"); -# endif -# elif defined(Q_OS_AIX) +# endif +# elif defined(Q_OS_AIX) validSuffixList << QLatin1String("a") << QLatin1String("so"); -# elif defined(Q_OS_UNIX) +# elif defined(Q_OS_DARWIN) + // On Apple platforms, dylib look like libmylib.1.0.0.dylib + if (suffixes.last() == QLatin1String("dylib")) + return true; + + validSuffixList << QLatin1String("so") << QLatin1String("bundle"); +# elif defined(Q_OS_UNIX) validSuffixList << QLatin1String("so"); -# endif +# endif // Examples of valid library names: // libfoo.so @@ -669,9 +663,7 @@ bool QLibrary::isLibrary(const QString &fileName) if (i != suffixPos) suffixes.at(i).toInt(&valid); return valid; -# endif #endif - } typedef const char * (*QtPluginQueryVerificationDataFunction)(); diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index a14c193bad..e6c70ecb55 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -96,7 +96,7 @@ void qt_create_tls() { if (qt_current_thread_data_tls_index != TLS_OUT_OF_INDEXES) return; - static QMutex mutex; + static QBasicMutex mutex; QMutexLocker locker(&mutex); qt_current_thread_data_tls_index = TlsAlloc(); } @@ -166,7 +166,7 @@ void QAdoptedThread::init() static QVector<HANDLE> qt_adopted_thread_handles; static QVector<QThread *> qt_adopted_qthreads; -static QMutex qt_adopted_thread_watcher_mutex; +static QBasicMutex qt_adopted_thread_watcher_mutex; static DWORD qt_adopted_thread_watcher_id = 0; static HANDLE qt_adopted_thread_wakeup = 0; diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index be53c51c48..f6164e2297 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -230,12 +230,39 @@ // SSE4.2 intrinsics #if defined(__SSE4_2__) || (defined(QT_COMPILER_SUPPORTS_SSE4_2) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)) #include <nmmintrin.h> + +# if defined(__SSE4_2__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) +// POPCNT instructions: +// All processors that support SSE4.2 support POPCNT +// (but neither MSVC nor the Intel compiler define this macro) +# define __POPCNT__ 1 +# endif #endif // AVX intrinsics #if defined(__AVX__) || (defined(QT_COMPILER_SUPPORTS_AVX) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)) // immintrin.h is the ultimate header, we don't need anything else after this #include <immintrin.h> + +# if defined(__AVX__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) +// AES, PCLMULQDQ instructions: +// All processors that support AVX support AES, PCLMULQDQ +// (but neither MSVC nor the Intel compiler define these macros) +# define __AES__ 1 +# define __PCLMUL__ 1 +# endif + +# if defined(__AVX2__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) +// F16C & RDRAND instructions: +// All processors that support AVX2 support F16C & RDRAND: +// (but neither MSVC nor the Intel compiler define these macros) +# define __F16C__ 1 +# define __RDRND__ 1 +# endif +#endif + +#if defined(__AES__) || defined(__PCLMUL__) +# include <wmmintrin.h> #endif #define QT_FUNCTION_TARGET_STRING_SSE2 "sse2" @@ -255,7 +282,10 @@ #define QT_FUNCTION_TARGET_STRING_AVX512IFMA "avx512ifma" #define QT_FUNCTION_TARGET_STRING_AVX512VBMI "avx512vbmi" -#define QT_FUNCTION_TARGET_STRING_F16C "f16c" +#define QT_FUNCTION_TARGET_STRING_AES "aes,sse4.2" +#define QT_FUNCTION_TARGET_STRING_PCLMUL "pclmul,sse4.2" +#define QT_FUNCTION_TARGET_STRING_POPCNT "popcnt" +#define QT_FUNCTION_TARGET_STRING_F16C "f16c,avx" #define QT_FUNCTION_TARGET_STRING_RDRAND "rdrnd" #define QT_FUNCTION_TARGET_STRING_BMI "bmi" #define QT_FUNCTION_TARGET_STRING_BMI2 "bmi2" diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.qdoc index 0ea47b1a1a..0ea47b1a1a 100644 --- a/src/corelib/tools/qvector.cpp +++ b/src/corelib/tools/qvector.qdoc diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index 4c215474fa..b93ec824ed 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -110,7 +110,6 @@ SOURCES += \ tools/qtextboundaryfinder.cpp \ tools/qtimeline.cpp \ tools/qunicodetools.cpp \ - tools/qvector.cpp \ tools/qvsnprintf.cpp \ tools/qversionnumber.cpp |