diff options
20 files changed, 210 insertions, 273 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 f0f47fe884..356dc21a1f 100644 --- a/examples/network/torrent/torrentclient.cpp +++ b/examples/network/torrent/torrentclient.cpp @@ -64,7 +64,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 <QtGui/QImage> #include <QtCore/QPropertyAnimation> -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 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(); } 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 <QThread> -//! [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 <QtCore> #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/qmake/generators/mac/pbuilder_pbx.h b/qmake/generators/mac/pbuilder_pbx.h index a08dc7c2bd..8813a190a9 100644 --- a/qmake/generators/mac/pbuilder_pbx.h +++ b/qmake/generators/mac/pbuilder_pbx.h @@ -84,7 +84,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() 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 <QMutex> #include <QThreadStorage> -#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 <QThread> - -//! [0] -class MyThread : public QThread -{ - Q_OBJECT - -protected: - void run(); -}; -//! [0] diff --git a/src/corelib/doc/src/threads-basics.qdoc b/src/corelib/doc/src/threads-basics.qdoc index dd5267f0ba..5a5c003210 100644 --- a/src/corelib/doc/src/threads-basics.qdoc +++ b/src/corelib/doc/src/threads-basics.qdoc @@ -172,109 +172,16 @@ \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 - 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 diff --git a/src/corelib/doc/src/threads.qdoc b/src/corelib/doc/src/threads.qdoc index 67a986d73e..9b80f0d200 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,7 +59,7 @@ \list \li \l{Recommended Reading} \li \l{The Threading Classes} - \li \l{Starting Threads with QThread} + \li \l{Multithreading Technologies in Qt} \li \l{Synchronizing Threads} \li \l{Reentrancy and Thread-Safety} \li \l{Threads and QObjects} @@ -112,59 +112,182 @@ */ /*! - \page threads-starting.html - \title Starting Threads with QThread + \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 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. + 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 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 + \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}} + + + \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 */ /*! \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 diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index ac7052f3a1..5f12141d2a 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 */ @@ -834,13 +833,12 @@ const QString::Null QString::null = { }; /*! \typedef QString::const_reference - The QString::const_reference typedef provides an STL-style - const reference for a QString element (QChar). + This typedef provides an STL-style const reference for a QString element (QChar). */ /*! \typedef QString::reference - The QString::reference typedef provides an STL-style + This typedef provides an STL-style reference for a QString element (QChar). */ @@ -860,8 +858,7 @@ const QString::Null QString::null = { }; /*! \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() 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<AdaptorData> AdaptorMap; 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 013896bd32..515eab6dfe 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -140,16 +140,24 @@ public: { typedef QVector<ObjectTreeNode> 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; } +#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 || activeChildren; } + { return obj || !children.isEmpty(); } QString name; union { @@ -157,7 +165,6 @@ public: QDBusVirtualObject *treeNode; }; int flags; - int activeChildren; DataList children; }; diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index e5f3fbdc53..d797fbfb99 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); } } 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) \ diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp index 05d5f94e3d..75b17df759 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 <size_t N> + ushortarray(unsigned short (&array)[N]) { - if (array) - memcpy(points, array, sizeof(points)); + memcpy(points, array, N*sizeof(unsigned short)); } unsigned short points[100]; |