summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/network/torrent/peerwireclient.cpp1
-rw-r--r--examples/network/torrent/torrentclient.cpp1
-rw-r--r--examples/opengl/pbuffers/cube.cpp2
-rw-r--r--examples/opengl/shared/qtlogo.cpp3
-rw-r--r--examples/sql/masterdetail/mainwindow.cpp2
-rw-r--r--examples/widgets/tutorials/threads/hellothread/hellothread.cpp3
-rw-r--r--examples/widgets/tutorials/threads/hellothread/hellothread.h5
-rw-r--r--examples/widgets/tutorials/threads/hellothread/main.cpp2
-rw-r--r--qmake/generators/mac/pbuilder_pbx.h2
-rw-r--r--src/corelib/doc/snippets/threads/threads.cpp10
-rw-r--r--src/corelib/doc/snippets/threads/threads.h51
-rw-r--r--src/corelib/doc/src/threads-basics.qdoc105
-rw-r--r--src/corelib/doc/src/threads.qdoc213
-rw-r--r--src/corelib/tools/qstring.cpp11
-rw-r--r--src/dbus/qdbusabstractadaptor_p.h4
-rw-r--r--src/dbus/qdbusconnection.cpp3
-rw-r--r--src/dbus/qdbusconnection_p.h15
-rw-r--r--src/dbus/qdbusintegrator.cpp41
-rw-r--r--tests/auto/corelib/io/qsettings/tst_qsettings.cpp2
-rw-r--r--tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp7
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];