From bb07737614d3fdf867e8e5da835554ae731ba04f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 19 Nov 2014 14:14:36 -0800 Subject: Fix the %{time} printing to *not* default to the process's time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default should be the actual time of day. Showing the process's time is the optional case. In the future, we'll provide a way to showing the monotonic reference time ("boot") and we should improve the detection of actual application runtime. Change-Id: I41936d77ab9fad2073dc0ce1c97cabe57ec39f16 Reviewed-by: Jan Arve Sæther Reviewed-by: Shawn Rutledge --- src/corelib/global/qlogging.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 39c5ac602e..843ec6b0ca 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1201,11 +1201,14 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con } #endif } else if (token == timeTokenC) { - quint64 ms = pattern->timer.elapsed(); - if (pattern->timeFormat.isEmpty()) + if (pattern->timeFormat == QLatin1String("process")) { + quint64 ms = pattern->timer.elapsed(); message.append(QString().sprintf("%6d.%03d", uint(ms / 1000), uint(ms % 1000))); - else - message.append(pattern->startTime.addMSecs(ms).toString(pattern->timeFormat)); + } else if (pattern->timeFormat.isEmpty()) { + message.append(QDateTime::currentDateTime().toString(Qt::ISODate)); + } else { + message.append(QDateTime::currentDateTime().toString(pattern->timeFormat)); + } #endif } else if (token == ifCategoryTokenC) { if (!context.category || (strcmp(context.category, "default") == 0)) @@ -1550,9 +1553,10 @@ void qErrnoWarning(int code, const char *msg, ...) \row \li \c %{pid} \li QCoreApplication::applicationPid() \row \li \c %{threadid} \li ID of current thread \row \li \c %{type} \li "debug", "warning", "critical" or "fatal" - \row \li \c %{time} \li time of the message, in seconds since the process started - \row \li \c %{time format} \li system time when the message occurred, formatted by - passing the \c format to \l QDateTime::toString() + \row \li \c %{time process} \li time of the message, in seconds since the process started (the token "process" is literal) + \row \li \c %{time [format]} \li system time when the message occurred, formatted by + passing the \c format to \l QDateTime::toString(). If the format is + not specified, the format of Qt::ISODate is used. \row \li \c{%{backtrace [depth=N] [separator="..."]}} \li A backtrace with the number of frames specified by the optional \c depth parameter (defaults to 5), and separated by the optional \c separator parameter (defaults to "|"). -- cgit v1.2.3 From f9408cc81c7d3cb3fa212005fb30cd8318ebf247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Fri, 21 Nov 2014 11:33:09 +0100 Subject: Android: protect global jni cache. This fixes a issue that has been neglected for a while, namely, that the access to the global jni caches where not sufficiently protected for concurrent usage. This change also fixes an issue with the thread-name storage. Task-number: QTBUG-42755 Change-Id: I22f95ae7f44d1f6a13e289e52b050d98ccb9fb28 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/kernel/qjni.cpp | 83 +++++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 25 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index b179323fdc..9d74fd69de 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -37,6 +37,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -45,11 +46,6 @@ static inline QString keyBase() return QStringLiteral("%1%2%3"); } -static inline QByteArray threadBaseName() -{ - return QByteArrayLiteral("QtThread-"); -} - static QString qt_convertJString(jstring string) { QJNIEnvironmentPrivate env; @@ -74,6 +70,7 @@ static inline bool exceptionCheckAndClear(JNIEnv *env) typedef QHash JClassHash; Q_GLOBAL_STATIC(JClassHash, cachedClasses) +Q_GLOBAL_STATIC(QReadWriteLock, cachedClassesLock) static QString toDotEncodedClassName(const char *className) { @@ -82,8 +79,9 @@ static QString toDotEncodedClassName(const char *className) static jclass getCachedClass(const QString &classDotEnc, bool *isCached = 0) { - QHash::iterator it = cachedClasses->find(classDotEnc); - const bool found = (it != cachedClasses->end()); + QReadLocker locker(cachedClassesLock); + const QHash::const_iterator &it = cachedClasses->constFind(classDotEnc); + const bool found = (it != cachedClasses->constEnd()); if (isCached != 0) *isCached = found; @@ -102,6 +100,12 @@ static jclass loadClassDotEnc(const QString &classDotEnc, JNIEnv *env) if (!classLoader.isValid()) return 0; + QWriteLocker locker(cachedClassesLock); + // did we lose the race? + const QHash::const_iterator &it = cachedClasses->constFind(classDotEnc); + if (it != cachedClasses->constEnd()) + return it.value(); + QJNIObjectPrivate stringName = QJNIObjectPrivate::fromString(classDotEnc); QJNIObjectPrivate classObject = classLoader.callObjectMethod("loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", @@ -121,6 +125,7 @@ inline static jclass loadClass(const char *className, JNIEnv *env) typedef QHash JMethodIDHash; Q_GLOBAL_STATIC(JMethodIDHash, cachedMethodID) +Q_GLOBAL_STATIC(QReadWriteLock, cachedMethodIDLock) static jmethodID getCachedMethodID(JNIEnv *env, jclass clazz, @@ -128,11 +133,24 @@ static jmethodID getCachedMethodID(JNIEnv *env, const char *sig, bool isStatic = false) { - jmethodID id = 0; // TODO: We need to use something else then the ref. from clazz to avoid collisions. - QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig)); - QHash::iterator it = cachedMethodID->find(key); - if (it == cachedMethodID->end()) { + const QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig)); + QHash::const_iterator it; + + { + QReadLocker locker(cachedMethodIDLock); + it = cachedMethodID->constFind(key); + if (it != cachedMethodID->constEnd()) + return it.value(); + } + + { + QWriteLocker locker(cachedMethodIDLock); + it = cachedMethodID->constFind(key); + if (it != cachedMethodID->constEnd()) + return it.value(); + + jmethodID id = 0; if (isStatic) id = env->GetStaticMethodID(clazz, name, sig); else @@ -142,14 +160,13 @@ static jmethodID getCachedMethodID(JNIEnv *env, id = 0; cachedMethodID->insert(key, id); - } else { - id = it.value(); + return id; } - return id; } typedef QHash JFieldIDHash; Q_GLOBAL_STATIC(JFieldIDHash, cachedFieldID) +Q_GLOBAL_STATIC(QReadWriteLock, cachedFieldIDLock) static jfieldID getCachedFieldID(JNIEnv *env, jclass clazz, @@ -157,10 +174,23 @@ static jfieldID getCachedFieldID(JNIEnv *env, const char *sig, bool isStatic = false) { - jfieldID id = 0; - QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig)); - QHash::iterator it = cachedFieldID->find(key); - if (it == cachedFieldID->end()) { + const QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig)); + QHash::const_iterator it; + + { + QReadLocker locker(cachedFieldIDLock); + it = cachedFieldID->constFind(key); + if (it != cachedFieldID->constEnd()) + return it.value(); + } + + { + QWriteLocker locker(cachedFieldIDLock); + it = cachedFieldID->constFind(key); + if (it != cachedFieldID->constEnd()) + return it.value(); + + jfieldID id = 0; if (isStatic) id = env->GetStaticFieldID(clazz, name, sig); else @@ -170,10 +200,8 @@ static jfieldID getCachedFieldID(JNIEnv *env, id = 0; cachedFieldID->insert(key, id); - } else { - id = it.value(); + return id; } - return id; } class QJNIEnvironmentPrivateTLS @@ -187,14 +215,14 @@ public: Q_GLOBAL_STATIC(QThreadStorage, jniEnvTLS) +static const char qJniThreadName[] = "QtThread"; + QJNIEnvironmentPrivate::QJNIEnvironmentPrivate() : jniEnv(0) { JavaVM *vm = QtAndroidPrivate::javaVM(); if (vm->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) == JNI_EDETACHED) { - const qulonglong id = reinterpret_cast(QThread::currentThreadId()); - const QByteArray threadName = threadBaseName() + QByteArray::number(id); - JavaVMAttachArgs args = { JNI_VERSION_1_6, threadName, Q_NULLPTR }; + JavaVMAttachArgs args = { JNI_VERSION_1_6, qJniThreadName, Q_NULLPTR }; if (vm->AttachCurrentThread(&jniEnv, &args) != JNI_OK) return; } @@ -223,6 +251,12 @@ jclass QJNIEnvironmentPrivate::findClass(const char *className, JNIEnv *env) return clazz; if (env != 0) { // We got an env. pointer (We expect this to be the right env. and call FindClass()) + QWriteLocker locker(cachedClassesLock); + const QHash::const_iterator &it = cachedClasses->constFind(classDotEnc); + // Did we lose the race? + if (it != cachedClasses->constEnd()) + return it.value(); + jclass fclazz = env->FindClass(className); if (!exceptionCheckAndClear(env)) { clazz = static_cast(env->NewGlobalRef(fclazz)); @@ -400,7 +434,6 @@ QJNIObjectPrivate::QJNIObjectPrivate(jobject obj) d->m_jclass = static_cast(env->NewGlobalRef(objectClass)); env->DeleteLocalRef(objectClass); } - template <> void QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const { -- cgit v1.2.3 From 5ed2f422fc3c80731be7a07da3875aaa5572d4e6 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Fri, 31 Oct 2014 14:20:20 +0100 Subject: Doc: corrected autolink errors corelib/io Task-number: QTBUG-40362 Change-Id: I1cdbde1f6b003556ba4b5e97a49c6d918518da0d Reviewed-by: Venugopal Shivashankar Reviewed-by: Jerome Pasion --- src/corelib/codecs/qtextcodec.cpp | 4 ++-- src/corelib/io/qdebug.cpp | 4 ++-- src/corelib/io/qfiledevice.cpp | 6 +++--- src/corelib/io/qloggingcategory.cpp | 8 ++++---- src/corelib/io/qprocess.cpp | 10 +++++----- src/corelib/io/qstandardpaths.cpp | 8 ++++---- src/corelib/io/qtemporarydir.cpp | 2 +- src/corelib/io/qtextstream.cpp | 16 ++++++++-------- src/corelib/io/qurl.cpp | 13 +++++++------ 9 files changed, 36 insertions(+), 35 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index d2857c03b6..6eae9e598d 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -380,7 +380,7 @@ QTextCodec::ConverterState::~ConverterState() If Qt is compiled with ICU support enabled, most codecs supported by ICU will also be available to the application. - QTextCodecs can be used as follows to convert some locally encoded + \l {QTextCodec}s can be used as follows to convert some locally encoded string to Unicode. Suppose you have some string encoded in Russian KOI8-R encoding, and want to convert it to Unicode. The simple way to do it is like this: @@ -453,7 +453,7 @@ QTextCodec::ConverterState::~ConverterState() \li Converts a Unicode string to an 8-bit character string. \endtable - \sa QTextStream, QTextDecoder, QTextEncoder, {Codecs Example} + \sa QTextStream, QTextDecoder, QTextEncoder, {Text Codecs Example} */ /*! diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp index c1e0125cb1..5c77ccdcbf 100644 --- a/src/corelib/io/qdebug.cpp +++ b/src/corelib/io/qdebug.cpp @@ -403,8 +403,8 @@ QDebug &QDebug::resetFormat() \brief Convenience class for custom QDebug operators Saves the settings used by QDebug, and restores them upon destruction, - then calls maybeSpace(), to separate arguments with a space if - autoInsertSpaces() was true at the time of constructing the QDebugStateSaver. + then calls \l {QDebug::maybeSpace()}{maybeSpace()}, to separate arguments with a space if + \l {QDebug::autoInsertSpaces()}{autoInsertSpaces()} was true at the time of constructing the QDebugStateSaver. The automatic insertion of spaces between writes is one of the settings that QDebugStateSaver stores for the duration of the current block. diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp index 598347a56f..29b59f1dcc 100644 --- a/src/corelib/io/qfiledevice.cpp +++ b/src/corelib/io/qfiledevice.cpp @@ -240,7 +240,7 @@ bool QFileDevice::isSequential() const Returns the file handle of the file. This is a small positive integer, suitable for use with C library - functions such as fdopen() and fcntl(). On systems that use file + functions such as \c fdopen() and \c fcntl(). On systems that use file descriptors for sockets (i.e. Unix systems, but not Windows) the handle can be used with QSocketNotifier as well. @@ -389,9 +389,9 @@ bool QFileDevice::atEnd() const return false. Seeking beyond the end of a file: - If the position is beyond the end of a file, then seek() shall not + If the position is beyond the end of a file, then seek() will not immediately extend the file. If a write is performed at this position, - then the file shall be extended. The content of the file between the + then the file will be extended. The content of the file between the previous end of file and the newly written data is UNDEFINED and varies between platforms and file systems. */ diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index fef48a9040..79d20601a6 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -149,10 +149,10 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift) Order of evaluation: \list - \li Rules from QtProject/qtlogging.ini - \li Rules set by \l setFilterRules() - \li Rules from file in \c QT_LOGGING_CONF - \li Rules from environment variable QT_LOGGING_RULES + \li QtProject/qtlogging.ini + \li \l setFilterRules() + \li \c QT_LOGGING_CONF + \li \c QT_LOGGING_RULES \endlist The \c QtProject/qtlogging.ini file is looked up in all directories returned diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index e76a836954..a234050777 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1853,8 +1853,8 @@ void QProcess::setProcessState(ProcessState state) /*! This function is called in the child process context just before the - program is executed on Unix or Mac OS X (i.e., after \e fork(), but before - \e execve()). Reimplement this function to do last minute initialization + program is executed on Unix or OS X (i.e., after \c fork(), but before + \c execve()). Reimplement this function to do last minute initialization of the child process. Example: \snippet code/src_corelib_io_qprocess.cpp 4 @@ -1864,7 +1864,7 @@ void QProcess::setProcessState(ProcessState state) execution, your workaround is to emit finished() and then call exit(). - \warning This function is called by QProcess on Unix and Mac OS X + \warning This function is called by QProcess on Unix and OS X only. On Windows and QNX, it is not called. */ void QProcess::setupChildProcess() @@ -2272,7 +2272,7 @@ void QProcess::setArguments(const QStringList &arguments) On Windows, terminate() posts a WM_CLOSE message to all toplevel windows of the process and then to the main thread of the process itself. On Unix - and Mac OS X the SIGTERM signal is sent. + and OS X the \c SIGTERM signal is sent. Console applications on Windows that do not run an event loop, or whose event loop does not handle the WM_CLOSE message, can only be terminated by @@ -2289,7 +2289,7 @@ void QProcess::terminate() /*! Kills the current process, causing it to exit immediately. - On Windows, kill() uses TerminateProcess, and on Unix and Mac OS X, the + On Windows, kill() uses TerminateProcess, and on Unix and OS X, the SIGKILL signal is sent to the process. \sa terminate() diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp index c206e432f6..538292f0a5 100644 --- a/src/corelib/io/qstandardpaths.cpp +++ b/src/corelib/io/qstandardpaths.cpp @@ -588,11 +588,11 @@ QString QStandardPaths::displayName(StandardLocation type) GenericCacheLocation, CacheLocation. Other locations are not affected. - On Unix, XDG_DATA_HOME is set to ~/.qttest/share, XDG_CONFIG_HOME is - set to ~/.qttest/config, and XDG_CACHE_HOME is set to ~/.qttest/cache. + On Unix, \c XDG_DATA_HOME is set to \e ~/.qttest/share, \c XDG_CONFIG_HOME is + set to \e ~/.qttest/config, and \c XDG_CACHE_HOME is set to \e ~/.qttest/cache. - On Mac, data goes to "~/.qttest/Application Support", cache goes to - ~/.qttest/Cache, and config goes to ~/.qttest/Preferences. + On OS X, data goes to \e ~/.qttest/Application Support, cache goes to + \e ~/.qttest/Cache, and config goes to \e ~/.qttest/Preferences. On Windows, everything goes to a "qttest" directory under Application Data. */ diff --git a/src/corelib/io/qtemporarydir.cpp b/src/corelib/io/qtemporarydir.cpp index 7ce37fd320..5e0def74ee 100644 --- a/src/corelib/io/qtemporarydir.cpp +++ b/src/corelib/io/qtemporarydir.cpp @@ -180,7 +180,7 @@ void QTemporaryDirPrivate::create(const QString &templateName) \snippet code/src_corelib_io_qtemporarydir.cpp 0 It is very important to test that the temporary directory could be - created, using isValid(). Do not use exists(), since a default-constructed + created, using isValid(). Do not use \l {QDir::exists()}{exists()}, since a default-constructed QDir represents the current directory, which exists. The path to the temporary dir can be found by calling path(). diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 66727e7dc4..089a915a36 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -85,8 +85,8 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384; \li Chunk by chunk, by calling readLine() or readAll(). - \li Word by word. QTextStream supports streaming into QStrings, - QByteArrays and char* buffers. Words are delimited by space, and + \li Word by word. QTextStream supports streaming into \l {QString}s, + \l {QByteArray}s and char* buffers. Words are delimited by space, and leading white space is automatically skipped. \li Character by character, by streaming into QChar or char types. @@ -158,7 +158,7 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384; parameter: qSetFieldWidth(), qSetPadChar(), and qSetRealNumberPrecision(). - \sa QDataStream, QIODevice, QFile, QBuffer, QTcpSocket, {Codecs Example} + \sa QDataStream, QIODevice, QFile, QBuffer, QTcpSocket, {Text Codecs Example} */ /*! \enum QTextStream::RealNumberNotation @@ -1531,7 +1531,7 @@ bool QTextStream::atEnd() const QString. Avoid this function when working on large files, as it will consume a significant amount of memory. - Calling readLine() is better if you do not know how much data is + Calling \l {QTextStream::readLine()}{readLine()} is better if you do not know how much data is available. \sa readLine() @@ -1556,9 +1556,9 @@ QString QTextStream::readAll() The returned line has no trailing end-of-line characters ("\\n" or "\\r\\n"), so calling QString::trimmed() is unnecessary. - If the stream has read to the end of the file, readLine() will return a - null QString. For strings, or for devices that support it, you can - explicitly test for the end of the stream using atEnd(). + If the stream has read to the end of the file, \l {QTextStream::readLine()}{readLine()} + will return a null QString. For strings, or for devices that support it, + you can explicitly test for the end of the stream using atEnd(). \sa readAll(), QIODevice::readLine() */ @@ -2790,7 +2790,7 @@ QTextStream &endl(QTextStream &stream) /*! \relates QTextStream - Calls QTextStream::flush() on \a stream and returns \a stream. + Calls \l{QTextStream::flush()}{flush()} on \a stream and returns \a stream. \sa endl(), reset(), {QTextStream manipulators} */ diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index d4c5e03058..d4c5a34cef 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -2671,8 +2671,8 @@ void QUrl::setQuery(const QUrlQuery &query) Sets the query string of the URL to an encoded version of \a query. The contents of \a query are converted to a string internally, each pair delimited by the character returned by - queryPairDelimiter(), and the key and value are delimited by - queryValueDelimiter(). + \l {QUrlQuery::queryPairDelimiter()}{queryPairDelimiter()}, and the key and value are delimited by + \l {QUrlQuery::queryValueDelimiter()}{queryValueDelimiter()} \note This method does not encode spaces (ASCII 0x20) as plus (+) signs, like HTML forms do. If you need that kind of encoding, you must encode @@ -2691,8 +2691,8 @@ void QUrl::setQuery(const QUrlQuery &query) Sets the query string of the URL to the encoded version of \a query. The contents of \a query are converted to a string internally, each pair delimited by the character returned by - queryPairDelimiter(), and the key and value are delimited by - queryValueDelimiter(). + \l {QUrlQuery::queryPairDelimiter()}{queryPairDelimiter()}, and the key and value are delimited by + \l {QUrlQuery::queryValueDelimiter()}{queryValueDelimiter()}. \obsolete Use QUrlQuery and setQuery(). @@ -2709,8 +2709,9 @@ void QUrl::setQuery(const QUrlQuery &query) The key-value pair is encoded before it is added to the query. The pair is converted into separate strings internally. The \a key and \a value is first encoded into UTF-8 and then delimited by the - character returned by queryValueDelimiter(). Each key-value pair is - delimited by the character returned by queryPairDelimiter(). + character returned by \l {QUrlQuery::queryValueDelimiter()}{queryValueDelimiter()}. + Each key-value pair is delimited by the character returned by + \l {QUrlQuery::queryPairDelimiter()}{queryPairDelimiter()} \note This method does not encode spaces (ASCII 0x20) as plus (+) signs, like HTML forms do. If you need that kind of encoding, you must encode -- cgit v1.2.3