From e19e1aae6990e46c766c5f7af02dfb5ffbf7c169 Mon Sep 17 00:00:00 2001 From: Chris Meyer Date: Fri, 13 Sep 2013 00:43:07 +0200 Subject: Revert recent attempt to fix Invalid Drawable error on Mac. This reverts commit 59fd36bb914cae248d3c5100dd734d6d90a58dca, which caused other drawing problems. Change-Id: I3bb75fd3ca1cd21ffbb9ef5474266f4cd615a64a Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qnsview.h | 1 - src/plugins/platforms/cocoa/qnsview.mm | 9 +++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index a7664887bf..3ee994427b 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -70,7 +70,6 @@ QT_END_NAMESPACE Qt::KeyboardModifiers currentWheelModifiers; bool m_subscribesForGlobalFrameNotifications; QCocoaGLContext *m_glContext; - bool m_drawRectHasBeenCalled; bool m_shouldSetGLContextinDrawRect; } diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 9fc74ea72b..c2ffe96f8c 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -87,7 +87,6 @@ static QTouchDevice *touchDevice = 0; m_sendKeyEvent = false; m_subscribesForGlobalFrameNotifications = false; m_glContext = 0; - m_drawRectHasBeenCalled = false; m_shouldSetGLContextinDrawRect = false; currentCustomDragTypes = 0; m_sendUpAsRightButton = false; @@ -154,9 +153,9 @@ static QTouchDevice *touchDevice = 0; - (void) setQCocoaGLContext:(QCocoaGLContext *)context { m_glContext = context; - if (m_drawRectHasBeenCalled) { - [m_glContext->nsOpenGLContext() setView:self]; - } else { + [m_glContext->nsOpenGLContext() setView:self]; + if (![m_glContext->nsOpenGLContext() view]) { + //was unable to set view m_shouldSetGLContextinDrawRect = true; } @@ -393,8 +392,6 @@ static QTouchDevice *touchDevice = 0; m_shouldSetGLContextinDrawRect = false; } - m_drawRectHasBeenCalled = true; - if (!m_backingStore) return; -- cgit v1.2.3 From 3e3297242a67e44559b32d60e0b341e7f8b5d9e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 13 Sep 2013 18:36:13 +0200 Subject: Xcode: Resolve extra compiler (e.g qrc) dependencies The Xcode generator relies on the generic makefile generator for extra compilers such as qrc and moc, by generating makefiles that are then executed as separate build steps in the Xcode build. These makefiles are generated by entering a special mode in the Xcode generator, in which case we _do_ want to resolve dependencies, so that e.g. the files referenced inside a qrc file are added as dependencies to the makefile rule that generates the qrc-cpp file. Change-Id: I96bdcb165e9774a6328ae1980986fa2c6b00c6d9 Reviewed-by: Andy Shaw --- qmake/generators/mac/pbuilder_pbx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/mac/pbuilder_pbx.h b/qmake/generators/mac/pbuilder_pbx.h index 255dd43348..aef373b549 100644 --- a/qmake/generators/mac/pbuilder_pbx.h +++ b/qmake/generators/mac/pbuilder_pbx.h @@ -83,7 +83,7 @@ protected: virtual QString escapeFilePath(const QString &path) const; ProString escapeFilePath(const ProString &path) const { return MakefileGenerator::escapeFilePath(path); } bool doPrecompiledHeaders() const { return false; } - virtual bool doDepends() const { return false; } //never necesary + virtual bool doDepends() const { return writingUnixMakefileGenerator && UnixMakefileGenerator::doDepends(); } }; inline ProjectBuilderMakefileGenerator::~ProjectBuilderMakefileGenerator() -- cgit v1.2.3 From 7c6b170198e2f6ed175de7ecefb9b1524ba23046 Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Sun, 8 Sep 2013 18:41:30 +0800 Subject: Doc: Fix copy+paste errors in the QString class ref Also bring text closer to the style guide at http://qt-project.org/wiki/CppDocumentationStyle Change-Id: I30b1c36ac125a10c002efeb36978ced0d7a8f8bf Reviewed-by: Jerome Pasion --- src/corelib/tools/qstring.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 37d28b0904..dd78d88732 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -805,8 +805,7 @@ const QString::Null QString::null = { }; /*! \typedef QString::const_iterator - The QString::const_iterator typedef provides an STL-style const - iterator for QString. + This typedef provides an STL-style const iterator for QString. \sa QString::iterator */ @@ -822,20 +821,17 @@ const QString::Null QString::null = { }; /*! \typedef QString::const_reference - The QString::const_reference typedef provides an STL-style - const reference for QString. + This typedef provides an STL-style const reference for QString. */ /*! \typedef QString::reference - The QString::const_reference typedef provides an STL-style - reference for QString. + This typedef provides an STL-style reference for QString. */ /*! \typedef QString::value_type - The QString::const_reference typedef provides an STL-style - value type for QString. + This typedef provides an STL-style value type for QString. */ /*! \fn QString::iterator QString::begin() -- cgit v1.2.3 From cddd16c2d564148f4d97dac894a054de1728641a Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Tue, 10 Sep 2013 19:23:38 +0800 Subject: Doc: Add an overview page to compare multithreading techniques Change-Id: I75e67ecb96423a3ebd82b32e6855378a73463fb7 Reviewed-by: Jerome Pasion Reviewed-by: Thiago Macieira --- src/corelib/doc/src/threads.qdoc | 122 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/src/corelib/doc/src/threads.qdoc b/src/corelib/doc/src/threads.qdoc index 160b717715..3d11c736cf 100644 --- a/src/corelib/doc/src/threads.qdoc +++ b/src/corelib/doc/src/threads.qdoc @@ -41,7 +41,7 @@ \ingroup frameworks-technologies - \nextpage Starting Threads with QThread + \nextpage Multithreading Technologies in Qt Qt provides thread support in the form of platform-independent threading classes, a thread-safe way of posting events, and @@ -59,6 +59,7 @@ \list \li \l{Recommended Reading} \li \l{The Threading Classes} + \li \l{Multithreading Technologies in Qt} \li \l{Starting Threads with QThread} \li \l{Synchronizing Threads} \li \l{Reentrancy and Thread-Safety} @@ -111,11 +112,130 @@ same native API. */ +/*! + \page threads-technologies.html + \title Multithreading Technologies in Qt + \ingroup qt-basic-concepts + \brief An overview and comparison of different ways to use threads in Qt. + + \ingroup frameworks-technologies + + \contentspage Thread Support in Qt + \previouspage Thread Support in Qt + \nextpage Starting Threads with QThread + + Qt offers many classes and functions for working with threads. Below are + three different approaches that Qt programmers can use to implement + multithreaded applications. + + + \section1 QThread: Low-Level API with Optional Event Loops + + QThread is the foundation of all thread control in Qt. Each QThread + instance represents and controls one thread. + + QThread can either be instantiated directly or subclassed. Instantiating a + QThread provides a parallel event loop, allowing QObject slots to be invoked + in a secondary thread. Subclassing a QThread allows the application to initialize + the new thread before starting its event loop, or to run parallel code + without an event loop. + + See the \l{QThread}{QThread class reference} and the \l{Threading and + Concurrent Programming Examples}{threading examples} for demonstrations on + how to use QThread. + + + \section1 QThreadPool and QRunnable: Reusing Threads + + Creating and destroying threads frequently can be expensive. To reduce this + overhead, existing threads can be reused for new tasks. QThreadPool is a + collection of reuseable QThreads. + + To run code in one of a QThreadPool's threads, reimplement QRunnable::run() + and instantiate the subclassed QRunnable. Use QThreadPool::start() to put + the QRunnable in the QThreadPool's run queue. When a thread becomes available, + the code within QRunnable::run() will execute in that thread. + + Each Qt application has a global thread pool, which is accessible through + QThreadPool::globalInstance(). This global thread pool automatically maintains + an optimal number of threads based on the number of cores in the CPU. However, + a separate QThreadPool can be created and managed explicitly. + + + \section1 Qt Concurrent: Using a High-level API + + The \l{Qt Concurrent} module provides high-level functions that deal with some + common parallel computation patterns: map, filter, and reduce. Unlike QThread + and QRunnable, these functions do not require the use of low-level threading + primitives such as mutexes or semaphores. \l {Qt Concurrent} will automatically + adjust the number of threads used according to the number of processor cores + available, so applications written today will continue to scale when deployed + later on a system with more cores. + + This module also provides the QtConcurrent::run() function, which can run + any function in a thread managed by the global QThreadPool. + + See the \l{Qt Concurrent} module documentation for details on the individual functions. + + + \section1 Comparison of Solutions + + \table + \header + \li Feature/Characteristic + \li QThread + \li QRunnable + \li Qt Concurrent\sup{*} + \row + \li Supports different thread priorities + \li Yes + \li + \li + \row + \li Supports an event loop + \li Yes + \li + \li + \row + \li Supports transferring data to the thread using signals + \li Yes (received by a worker QObject) + \li + \li + \row + \li Supports controlling the thread using signals + \li Yes (received by QThread) + \li + \li Yes (received by QFutureWatcher) + \row + \li Supports thread reuse + \li + \li Yes + \li Yes + \row + \li Task-oriented + \li + \li Yes + \li Yes + \row + \li High level API + \li + \li + \li Yes + \row + \li Supports pausing/resuming/canceling + \li + \li + \li Yes + \endtable + \sup{\e{*Except QtConcurrent::run(), which is like QRunnable}} +*/ + /*! \page threads-starting.html \title Starting Threads with QThread \contentspage Thread Support in Qt + \previouspage Multithreading Technologies in Qt \nextpage Synchronizing Threads A QThread instance represents a thread and provides the means to -- cgit v1.2.3 From 5852ddb110e63cc9d2271431a7776978c2249877 Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Sun, 8 Sep 2013 16:48:04 +0800 Subject: Doc: Move multithreading guidelines to the overview page It's helpful to see how to choose among different solutions, right after seeing short descriptions of all the solutions. - Some minor rewording was done during the move - The example about polling ports in a new thread was removed because there are better ways to do that without threads. Change-Id: I2cb571a4dbf9be93fb0ec88c60fb7406996c345b Reviewed-by: Olivier Goffart Reviewed-by: Jerome Pasion Reviewed-by: Thiago Macieira --- src/corelib/doc/src/threads-basics.qdoc | 66 ++------------------------------- src/corelib/doc/src/threads.qdoc | 56 +++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 64 deletions(-) diff --git a/src/corelib/doc/src/threads-basics.qdoc b/src/corelib/doc/src/threads-basics.qdoc index dd5267f0ba..353906f11a 100644 --- a/src/corelib/doc/src/threads-basics.qdoc +++ b/src/corelib/doc/src/threads-basics.qdoc @@ -172,69 +172,9 @@ \section2 Which Qt Thread Technology Should You Use? - Sometimes you want to do more than just running a method in the context of - another thread. You may want to have an object which lives in another - thread that provides a service to the GUI thread. Maybe you want another - thread to stay alive forever to poll hardware ports and send a signal to - the GUI thread when something noteworthy has happened. Qt provides - different solutions for developing threaded applications. The right - solution depends on the purpose of the new thread as well as on the - thread's lifetime. - - \table - \header - \li Lifetime of thread - \li Development task - \li Solution - \row - \li One call - \li Run one method within another thread and quit the thread when the - method is finished. - \li Qt provides different solutions: - \list - \li Write a function and run it with QtConcurrent::run() - \li Derive a class from QRunnable and run it in the global thread - pool with QThreadPool::globalInstance()->start() - \li Derive a class from QThread, reimplement the QThread::run() - method and use QThread::start() to run it. - \endlist - - \row - \li One call - \li Operations are to be performed on all items of a container. - Processing should be performed using all available cores. A common - example is to produce thumbnails from a list of images. - \li QtConcurrent provides the \l{QtConcurrent::}{map()} function for - applying operations on every container element, - \l{QtConcurrent::}{filter()} for selecting container elements, and - the option of specifying a reduce function for combining the - remaining elements. - \row - \li One call - \li A long running operation has to be put in another thread. During the - course of processing, status information should be sent to the GUI - thread. - \li Use QThread, reimplement run and emit signals as needed. Connect the - signals to the GUI thread's slots using queued signal/slot - connections. - - \row - \li Permanent - \li Have an object living in another thread and let it perform different - tasks upon request. - This means communication to and from the worker thread is required. - \li Derive a class from QObject and implement the necessary slots and - signals, move the object to a thread with a running event loop and - communicate with the object over queued signal/slot connections. - \row - \li Permanent - \li Have an object living in another thread, let the object perform - repeated tasks such as polling a port and enable communication with - the GUI thread. - \li Same as above but also use a timer in the worker thread to implement - polling. However, the best solution for polling is to avoid it - completely. Sometimes using QSocketNotifier is an alternative. - \endtable + See the \l{Multithreading Technologies in Qt} page for an introduction to the + different approaches to multithreading to Qt, and for guidelines on how to + choose among them. \section1 Qt Thread Basics diff --git a/src/corelib/doc/src/threads.qdoc b/src/corelib/doc/src/threads.qdoc index 3d11c736cf..79bd7a62a3 100644 --- a/src/corelib/doc/src/threads.qdoc +++ b/src/corelib/doc/src/threads.qdoc @@ -178,7 +178,14 @@ See the \l{Qt Concurrent} module documentation for details on the individual functions. - \section1 Comparison of Solutions + \section1 Choosing an Appropriate Approach + + As demonstrated above, Qt provides different solutions for developing threaded + applications. The right solution for a given application depends on the purpose + of the new thread and the thread's lifetime. Below is a comparison of Qt's + threading technologies, followed by recommended solutions for some example use cases. + + \section2 Comparison of Solutions \table \header @@ -228,6 +235,53 @@ \li Yes \endtable \sup{\e{*Except QtConcurrent::run(), which is like QRunnable}} + + + \section2 Example Use Cases + + \table + \header + \li Lifetime of thread + \li Operation + \li Solution + \row + \li One call + \li Run a linear function within another thread, optionally with progress + updates during the run. + \li Qt provides different solutions: + \list + \li Place the function in a reimplementation of QThread::run() and + start the QThread. Emit signals to update progress. OR + \li Place the function in a reimplementation of QRunnable::run() and + add the QRunnable to a QThreadPool. Write to a \l{Synchronizing + Threads}{thread-safe variable} to update progress. OR + \li Run the function using QtConcurrent::run(). Write to a \l{Synchronizing + Threads}{thread-safe variable} to update progress. + \endlist + \row + \li One call + \li Perform an operation on all items of a container, using all available + cores. For example, producing thumbnails from a list of images. + \li Use Qt Concurrent's \l{QtConcurrent::}{filter()} function to select + container elements, and the \l{QtConcurrent::}{map()} function to apply + an operation to each element. To fold the output into a single result, + use \l{QtConcurrent::}{filterReduced()} and \l{QtConcurrent::}{mapReduced()} + instead. + \row + \li Permanent + \li Have an object living in another thread that can perform different + tasks upon request and/or can receive new data to work with. + \li Subclass a QObject to create a worker. Instantiate this worker object + and a QThread. Move the worker to the new thread. Send commands or + data to the worker object over queued signal-slot connections. + \row + \li Permanent + \li Repeatedly perform an expensive operation in another thread, where the + thread does not need to receive any signals or events. + \li Write the infinite loop directly within a reimplementation of QThread::run(). + Start the thread without an event loop. Let the thread emit signals to + send data back to the GUI thread. + \endtable */ /*! -- cgit v1.2.3 From 6780f76ee0e9122b8c15861a85fd29a908724d72 Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Sun, 8 Sep 2013 17:33:41 +0800 Subject: Doc: Remove page about how to start QThreads Multiple issues: - Incomplete: It doesn't talk about instantiating a raw QThread - Redundant: Its contents are already presented in QThread's class ref - Incorrect: It is legal to create a QThread before a QCoreApplication - Irrelevant: The bit about QCoreApplication::exec() and the etymology of "GUI thread" is unrelated to the topic of starting threads Also remove snippets that are no longer used Change-Id: Ice1819845b5b2cf843719edaa7b0f4bbb1e8bd97 Reviewed-by: Olivier Goffart Reviewed-by: Jerome Pasion Reviewed-by: Thiago Macieira --- src/corelib/doc/snippets/threads/threads.cpp | 10 ----- src/corelib/doc/snippets/threads/threads.h | 51 -------------------------- src/corelib/doc/src/threads.qdoc | 55 +--------------------------- 3 files changed, 2 insertions(+), 114 deletions(-) delete mode 100644 src/corelib/doc/snippets/threads/threads.h diff --git a/src/corelib/doc/snippets/threads/threads.cpp b/src/corelib/doc/snippets/threads/threads.cpp index e6e74ae1e5..b399728658 100644 --- a/src/corelib/doc/snippets/threads/threads.cpp +++ b/src/corelib/doc/snippets/threads/threads.cpp @@ -42,16 +42,6 @@ #include #include -#include "threads.h" - -//! [0] -void MyThread::run() -//! [0] //! [1] -{ -//! [1] //! [2] -} -//! [2] - #define Counter ReentrantCounter //! [3] diff --git a/src/corelib/doc/snippets/threads/threads.h b/src/corelib/doc/snippets/threads/threads.h deleted file mode 100644 index 653ac54ddb..0000000000 --- a/src/corelib/doc/snippets/threads/threads.h +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -//! [0] -class MyThread : public QThread -{ - Q_OBJECT - -protected: - void run(); -}; -//! [0] diff --git a/src/corelib/doc/src/threads.qdoc b/src/corelib/doc/src/threads.qdoc index 79bd7a62a3..27aca86406 100644 --- a/src/corelib/doc/src/threads.qdoc +++ b/src/corelib/doc/src/threads.qdoc @@ -60,7 +60,6 @@ \li \l{Recommended Reading} \li \l{The Threading Classes} \li \l{Multithreading Technologies in Qt} - \li \l{Starting Threads with QThread} \li \l{Synchronizing Threads} \li \l{Reentrancy and Thread-Safety} \li \l{Threads and QObjects} @@ -122,7 +121,7 @@ \contentspage Thread Support in Qt \previouspage Thread Support in Qt - \nextpage Starting Threads with QThread + \nextpage Synchronizing Threads Qt offers many classes and functions for working with threads. Below are three different approaches that Qt programmers can use to implement @@ -284,61 +283,11 @@ \endtable */ -/*! - \page threads-starting.html - \title Starting Threads with QThread - - \contentspage Thread Support in Qt - \previouspage Multithreading Technologies in Qt - \nextpage Synchronizing Threads - - A QThread instance represents a thread and provides the means to - \l{QThread::start()}{start()} a thread, which will then execute the - reimplementation of QThread::run(). The \c run() implementation is for a - thread what the \c main() entry point is for the application. All code - executed in a call stack that starts in the \c run() function is executed - by the new thread, and the thread finishes when the function returns. - QThread emits signals to indicate that the thread started or finished - executing. - - \section1 Creating a Thread - - To create a thread, subclass QThread and reimplement its - \l{QThread::run()}{run()} function. For example: - - \snippet threads/threads.h 0 - \codeline - \snippet threads/threads.cpp 0 - \snippet threads/threads.cpp 1 - \dots - \snippet threads/threads.cpp 2 - - \section1 Starting a Thread - - Then, create an instance of the thread object and call - QThread::start(). Note that you must create the QApplication (or - QCoreApplication) object before you can create a QThread. - - The function will return immediately and the - main thread will continue. The code that appears in the - \l{QThread::run()}{run()} reimplementation will then be executed - in a separate thread. - - Creating threads is explained in more detail in the QThread - documentation. - - Note that QCoreApplication::exec() must always be called from the - main thread (the thread that executes \c{main()}), not from a - QThread. In GUI applications, the main thread is also called the - GUI thread because it's the only thread that is allowed to - perform GUI-related operations. -*/ - /*! \page threads-synchronizing.html \title Synchronizing Threads - \previouspage Starting Threads with QThread + \previouspage Multithreading Technologies in Qt \contentspage Thread Support in Qt \nextpage Reentrancy and Thread-Safety -- cgit v1.2.3 From 2171b057e3e6273ae065b2754acec26887ad5ddf Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Tue, 10 Sep 2013 21:08:01 +0800 Subject: Doc: Remove section about how to start threads - Incomplete: It doesn't talk about how to use a raw QThread, or QRunnable, or Qt Concurrent. - Redundant: Its contents are already presented in QThread's class ref, and the line before this section links to the "Multithreading Technologies in Qt" overview page which provides a more complete intro Also remove snippet markers that are no longer used. Change-Id: I89b7bd72f10c8ffdfd9b7772e2493050aafc9c88 Reviewed-by: Jerome Pasion Reviewed-by: Thiago Macieira --- .../tutorials/threads/hellothread/hellothread.cpp | 3 -- .../tutorials/threads/hellothread/hellothread.h | 5 ++- .../widgets/tutorials/threads/hellothread/main.cpp | 2 -- src/corelib/doc/src/threads-basics.qdoc | 39 ++-------------------- 4 files changed, 5 insertions(+), 44 deletions(-) diff --git a/examples/widgets/tutorials/threads/hellothread/hellothread.cpp b/examples/widgets/tutorials/threads/hellothread/hellothread.cpp index 4395b0cb2b..1b5088e0db 100644 --- a/examples/widgets/tutorials/threads/hellothread/hellothread.cpp +++ b/examples/widgets/tutorials/threads/hellothread/hellothread.cpp @@ -44,10 +44,7 @@ * demonstrates use of QThread, says hello in another thread and terminates */ -//! [1] -// hellothread/hellothread.cpp void HelloThread::run() { qDebug() << "hello from worker thread " << thread()->currentThreadId(); } -//! [1] diff --git a/examples/widgets/tutorials/threads/hellothread/hellothread.h b/examples/widgets/tutorials/threads/hellothread/hellothread.h index c2d8ad73ee..281f2c6cb5 100644 --- a/examples/widgets/tutorials/threads/hellothread/hellothread.h +++ b/examples/widgets/tutorials/threads/hellothread/hellothread.h @@ -42,13 +42,12 @@ #define HELLOTHREAD_H #include -//! [1] -// hellothread/hellothread.h + class HelloThread : public QThread { Q_OBJECT private: void run(); }; -//! [1] + #endif // HELLOTHREAD_H diff --git a/examples/widgets/tutorials/threads/hellothread/main.cpp b/examples/widgets/tutorials/threads/hellothread/main.cpp index 87660f97ee..8b4b00874f 100644 --- a/examples/widgets/tutorials/threads/hellothread/main.cpp +++ b/examples/widgets/tutorials/threads/hellothread/main.cpp @@ -41,7 +41,6 @@ #include #include "hellothread.h" -//! [1] int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); @@ -51,4 +50,3 @@ int main(int argc, char *argv[]) thread.wait(); // do not exit before the thread is completed! return 0; } -//! [1] diff --git a/src/corelib/doc/src/threads-basics.qdoc b/src/corelib/doc/src/threads-basics.qdoc index 353906f11a..5a5c003210 100644 --- a/src/corelib/doc/src/threads-basics.qdoc +++ b/src/corelib/doc/src/threads-basics.qdoc @@ -179,42 +179,9 @@ \section1 Qt Thread Basics - QThread is a very convenient cross platform abstraction of native platform - threads. Starting a thread is very simple. Let us look at a short piece of - code that generates another thread which says hello in that thread and then - exits. - - \snippet ../widgets/tutorials/threads/hellothread/hellothread.h 1 - - We derive a class from QThread and reimplement the \l{QThread::}{run()} - method. - - \snippet ../widgets/tutorials/threads/hellothread/hellothread.cpp 1 - - The run method contains the code that will be run in a separate thread. In - this example, a message containing the thread ID will be printed. - QThread::start() will call the method in another thread. - - \snippet ../widgets/tutorials/threads/hellothread/main.cpp 1 - - To start the thread, our thread object needs to be instantiated. The - \l{QThread::}{start()} method creates a new thread and calls the - reimplemented \l{QThread::}{run()} method in this new thread. Right after - \l{QThread::}{start()} is called, two program counters walk through the - program code. The main function starts with only the GUI thread running and - it should terminate with only the GUI thread running. Exiting the program - when another thread is still busy is a programming error, and therefore, - wait is called which blocks the calling thread until the - \l{QThread::}{run()} method has completed. - - This is the result of running the code: - - \code - //bad code - hello from GUI thread 3079423696 - hello from worker thread 3076111216 - \endcode - + The following sections describe how QObjects interact with threads, how + programs can safely access data from multiple threads, and how asynchronous + execution produces results without blocking a thread. \section2 QObject and Threads -- cgit v1.2.3 From 6827728d5ac0e878cf330ecaea09a0cb21a7424d Mon Sep 17 00:00:00 2001 From: John Brooks Date: Wed, 4 Sep 2013 00:21:32 -0600 Subject: Fix loss of valid dbus objects after unregisterObject Partial revert of 3c6bb0ed8bfc9a2c679f4154585a16e47275ad21 and 57aed703d21c3a360d95fd9f85396d1283d3fdd0. When registering an object that was previously unregistered but not yet garbage collected, the activeChildren count on the parent node was not incremented, which could result in other registered objects disappearing after a later unregisterObject. Copying objects in the tree is not free, but it's not expensive enough or used frequently enough to justify that error-prone logic. It's much safer to simply remove objects immediately. Change-Id: I3dc59c2ebd07b237518424fcd8ea7371a22d6d15 Reviewed-by: Robin Burchell Reviewed-by: Thiago Macieira --- src/dbus/qdbusconnection.cpp | 3 +-- src/dbus/qdbusconnection_p.h | 7 +++---- src/dbus/qdbusintegrator.cpp | 41 +++++++---------------------------------- 3 files changed, 11 insertions(+), 40 deletions(-) diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index a29ba4cb0f..320787c265 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -804,7 +804,7 @@ bool QDBusConnection::registerObject(const QString &path, QObject *object, Regis return false; if (options & QDBusConnectionPrivate::VirtualObject) { - if (options & SubPath && node->activeChildren) + if (options & SubPath && !node->children.isEmpty()) return false; } else { if ((options & ExportChildObjects && !node->children.isEmpty())) @@ -842,7 +842,6 @@ bool QDBusConnection::registerObject(const QString &path, QObject *object, Regis } } else { // add entry - ++node->activeChildren; node = node->children.insert(it, pathComponents.at(i)); } diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index c702de141a..a61fdaf6c3 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -140,16 +140,16 @@ public: { typedef QVector DataList; - inline ObjectTreeNode() : obj(0), flags(0), activeChildren(0) { } + inline ObjectTreeNode() : obj(0), flags(0) { } inline ObjectTreeNode(const QString &n) // intentionally implicit - : name(n), obj(0), flags(0), activeChildren(0) { } + : name(n), obj(0), flags(0) { } inline ~ObjectTreeNode() { } inline bool operator<(const QString &other) const { return name < other; } inline bool operator<(const QStringRef &other) const { return QStringRef(&name) < other; } inline bool isActive() const - { return obj || activeChildren; } + { return obj || !children.isEmpty(); } QString name; union { @@ -157,7 +157,6 @@ public: QDBusVirtualObject *treeNode; }; int flags; - int activeChildren; DataList children; }; diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 3f25f02bee..c324449b7d 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -587,46 +587,22 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg) return false; } -static void garbageCollectChildren(QDBusConnectionPrivate::ObjectTreeNode &node) -{ - int size = node.children.count(); - if (node.activeChildren == 0) { - // easy case - node.children.clear(); - } else if (size > node.activeChildren * 3 || (size > 20 && size * 2 > node.activeChildren * 3)) { - // rewrite the vector, keeping only the active children - // if the vector is large (> 20 items) and has one third of inactives - // or if the vector is small and has two thirds of inactives. - QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator end = node.children.end(); - QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = node.children.begin(); - QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator tgt = it; - for ( ; it != end; ++it) { - if (it->isActive()) - *tgt++ = qMove(*it); - } - ++tgt; - node.children.erase(tgt, end); - } -} - static void huntAndDestroy(QObject *needle, QDBusConnectionPrivate::ObjectTreeNode &haystack) { QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = haystack.children.begin(); - QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator end = haystack.children.end(); - for ( ; it != end; ++it) { - if (!it->isActive()) - continue; + + while (it != haystack.children.end()) { huntAndDestroy(needle, *it); if (!it->isActive()) - --haystack.activeChildren; + it = haystack.children.erase(it); + else + it++; } if (needle == haystack.obj) { haystack.obj = 0; haystack.flags = 0; } - - garbageCollectChildren(haystack); } static void huntAndUnregister(const QStringList &pathComponents, int i, QDBusConnection::UnregisterMode mode, @@ -639,7 +615,6 @@ static void huntAndUnregister(const QStringList &pathComponents, int i, QDBusCon if (mode == QDBusConnection::UnregisterTree) { // clear the sub-tree as well - node->activeChildren = 0; node->children.clear(); // can't disconnect the objects because we really don't know if they can // be found somewhere else in the path too } @@ -648,14 +623,12 @@ static void huntAndUnregister(const QStringList &pathComponents, int i, QDBusCon QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator end = node->children.end(); QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = std::lower_bound(node->children.begin(), end, pathComponents.at(i)); - if (it == end || it->name != pathComponents.at(i) || !it->isActive()) + if (it == end || it->name != pathComponents.at(i)) return; // node not found huntAndUnregister(pathComponents, i + 1, mode, it); if (!it->isActive()) - --node->activeChildren; - - garbageCollectChildren(*node); + node->children.erase(it); } } -- cgit v1.2.3 From 51cffbdcb7f2a88c3cde381fa6ca704fd723c242 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 14 Sep 2013 15:49:43 +0200 Subject: examples: remove unused static const variables They cause warnings on Clang. Change-Id: If599303f4a00c2a24f0a7c369299f3ea6fe7fc91 Reviewed-by: Giuseppe D'Angelo --- examples/network/torrent/peerwireclient.cpp | 1 - examples/network/torrent/torrentclient.cpp | 1 - examples/opengl/pbuffers/cube.cpp | 2 -- examples/opengl/shared/qtlogo.cpp | 3 --- 4 files changed, 7 deletions(-) diff --git a/examples/network/torrent/peerwireclient.cpp b/examples/network/torrent/peerwireclient.cpp index 0f77ba10d3..a0be01d363 100644 --- a/examples/network/torrent/peerwireclient.cpp +++ b/examples/network/torrent/peerwireclient.cpp @@ -49,7 +49,6 @@ static const int ConnectTimeout = 60 * 1000; static const int KeepAliveInterval = 30 * 1000; static const int RateControlTimerDelay = 2000; static const int MinimalHeaderSize = 48; -static const int FullHeaderSize = 68; static const char ProtocolId[] = "BitTorrent protocol"; static const char ProtocolIdSize = 19; diff --git a/examples/network/torrent/torrentclient.cpp b/examples/network/torrent/torrentclient.cpp index b5969e552e..2db74164ef 100644 --- a/examples/network/torrent/torrentclient.cpp +++ b/examples/network/torrent/torrentclient.cpp @@ -62,7 +62,6 @@ static const int RateControlTimerDelay = 1000; static const int MinimumTimeBeforeRevisit = 30; static const int MaxUploads = 4; static const int UploadScheduleInterval = 10000; -static const int EndGamePieces = 5; class TorrentPiece { public: diff --git a/examples/opengl/pbuffers/cube.cpp b/examples/opengl/pbuffers/cube.cpp index ffa08780d7..dc1bb23fea 100644 --- a/examples/opengl/pbuffers/cube.cpp +++ b/examples/opengl/pbuffers/cube.cpp @@ -44,8 +44,6 @@ #include #include -static const qreal FACE_SIZE = 0.4; - static const qreal speeds[] = { 3.8f, 4.4f, 5.6f }; static const qreal amplitudes[] = { 2.0f, 2.5f, 3.0f }; diff --git a/examples/opengl/shared/qtlogo.cpp b/examples/opengl/shared/qtlogo.cpp index ea175234ae..608f5b3f2b 100644 --- a/examples/opengl/shared/qtlogo.cpp +++ b/examples/opengl/shared/qtlogo.cpp @@ -49,10 +49,7 @@ static const qreal tee_height = 0.311126; static const qreal cross_width = 0.25; static const qreal bar_thickness = 0.113137; -static const qreal inside_diam = 0.20; -static const qreal outside_diam = 0.30; static const qreal logo_depth = 0.10; -static const int num_divisions = 32; //! [0] struct Geometry -- cgit v1.2.3 From 831e314fc3ddd5e1ed8246609df1debe6f5cd6f9 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 14 Sep 2013 15:52:03 +0200 Subject: examples: fix if (!foo == 0) Clang issues a warning for this. Change-Id: I1b9741d0260d43f864e404c693b5a459c5038b67 Reviewed-by: Giuseppe D'Angelo --- examples/sql/masterdetail/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/sql/masterdetail/mainwindow.cpp b/examples/sql/masterdetail/mainwindow.cpp index f3bd194c31..ee42a22d00 100644 --- a/examples/sql/masterdetail/mainwindow.cpp +++ b/examples/sql/masterdetail/mainwindow.cpp @@ -142,7 +142,7 @@ void MainWindow::showAlbumDetails(QModelIndex index) break; } } - if (!trackList->count() == 0) + if (trackList->count() != 0) trackList->show(); } -- cgit v1.2.3 From 95b62e5a71368fa7ff4552bea895c11559a706b1 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 14 Sep 2013 16:07:46 +0200 Subject: tst_QSettings: add missing () around a macro argument use 'val' was set to QList<...>() << ... << ... further down. Fixes a Clang warning. Change-Id: I5fe80d87dbe2c1d50652dfd7b6c5f4a9198cd467 Reviewed-by: Thiago Macieira --- tests/auto/corelib/io/qsettings/tst_qsettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index aec8d1b241..290d4ac240 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -2467,7 +2467,7 @@ void tst_QSettings::testEscapes() QString s = QSettingsPrivate::variantToString(v); \ QCOMPARE(s, escStr); \ QCOMPARE(QVariant(QSettingsPrivate::stringToVariant(escStr)), v); \ - QVERIFY(val == v.func()); \ + QVERIFY((val) == v.func()); \ } #define testBadEscape(escStr, vStr) \ -- cgit v1.2.3 From c8411a0281c5ebf830920bdce05160c8b0682248 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 14 Sep 2013 18:09:10 +0200 Subject: tst_qurlinternal: fix a use of memcpy on overlapping memory The old code smply copied 100 shorts from the pointer passed into the ushortarray ctor, regardless of the actual bounds of the original array. Fix by making the ctor take the array by deference, deducing the size as a template parameter, and only copying that much. Fixes asan trace: ==18660==ERROR: AddressSanitizer: memcpy-param-overlap: memory ranges [0x7fff3c56de00,0x7fff3c56dec8) and [0x7fff3c56dd60, 0x7fff3c56de28) overlap #0 0x457161 in memcpy asan_interceptors.cc:330 #1 0x4c40fe in ushortarray::ushortarray(unsigned short*) qtbase/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp:62 #2 0x4b0437 in ushortarray::ushortarray(unsigned short*) qtbase/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp:63 #3 0x47b643 in tst_QUrlInternal::idna_testsuite_data() qtbase/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp:119 ... Change-Id: Ie497bc8d337bc680a562482ca71ace535797ffb3 Reviewed-by: Thiago Macieira --- tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp index 2014045171..4b74dd7906 100644 --- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp +++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp @@ -56,10 +56,11 @@ #define STRINGPREP_BIDI_LEADTRAIL_NOT_RAL 5 struct ushortarray { - ushortarray(unsigned short *array = 0) + ushortarray() {} + template + ushortarray(unsigned short (&array)[N]) { - if (array) - memcpy(points, array, sizeof(points)); + memcpy(points, array, N*sizeof(unsigned short)); } unsigned short points[100]; -- cgit v1.2.3 From c40a48af997f57caa0ecfca0b247837ba5b2f89b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Alvarez?= Date: Sat, 14 Sep 2013 01:00:48 -0300 Subject: QtDBus: fix build on MSVC2008 Debug mode. Normally, searching for a V in a container of T using std::lower_bound only needs an operator<(T,V). But in MSVC2008 debug mode, STL algorithms perform some extra checks, such as ensuring the range passed to std::lower_bound is sorted. This adds a requirement for operator<(T,T) and operator<(V,T). QtDBus didn't compile on MSVC2008+Debug since 1e37d854 (Sept 2012!) because it missed those operator overloads for some private types. Task-number: QTBUG-33473 Change-Id: I18902d86e6c58349eb7ba3601dc383ad5431c460 Reviewed-by: Thiago Macieira --- src/dbus/qdbusabstractadaptor_p.h | 4 ++++ src/dbus/qdbusconnection_p.h | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/dbus/qdbusabstractadaptor_p.h b/src/dbus/qdbusabstractadaptor_p.h index 3dc8cd320e..284b0fb706 100644 --- a/src/dbus/qdbusabstractadaptor_p.h +++ b/src/dbus/qdbusabstractadaptor_p.h @@ -104,6 +104,10 @@ public: // typedefs { return QLatin1String(interface) < other; } inline bool operator<(const QByteArray &other) const { return interface < other; } +#if defined(Q_CC_MSVC) && _MSC_VER < 1600 + friend inline bool operator<(const QString &str, const AdaptorData &obj) + { return str < QLatin1String(obj.interface); } +#endif }; typedef QVector AdaptorMap; diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index a61fdaf6c3..7053bb5e01 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -148,6 +148,14 @@ public: { return name < other; } inline bool operator<(const QStringRef &other) const { return QStringRef(&name) < other; } +#if defined(Q_CC_MSVC) && _MSC_VER < 1600 + inline bool operator<(const ObjectTreeNode &other) const + { return name < other.name; } + friend inline bool operator<(const QString &str, const ObjectTreeNode &obj) + { return str < obj.name; } + friend inline bool operator<(const QStringRef &str, const ObjectTreeNode &obj) + { return str < QStringRef(&obj.name); } +#endif inline bool isActive() const { return obj || !children.isEmpty(); } -- cgit v1.2.3