summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qatomic.cpp4
-rw-r--r--src/corelib/thread/qatomic.h7
-rw-r--r--src/corelib/thread/qbasicatomic.h232
-rw-r--r--src/corelib/thread/qgenericatomic.h234
-rw-r--r--src/corelib/thread/qmutex.cpp4
-rw-r--r--src/corelib/thread/qmutex.h5
-rw-r--r--src/corelib/thread/qmutex_linux.cpp4
-rw-r--r--src/corelib/thread/qmutex_mac.cpp4
-rw-r--r--src/corelib/thread/qmutex_p.h8
-rw-r--r--src/corelib/thread/qmutex_unix.cpp4
-rw-r--r--src/corelib/thread/qmutex_win.cpp7
-rw-r--r--src/corelib/thread/qmutexpool.cpp4
-rw-r--r--src/corelib/thread/qmutexpool_p.h4
-rw-r--r--src/corelib/thread/qoldbasicatomic.h18
-rw-r--r--src/corelib/thread/qorderedmutexlocker_p.h4
-rw-r--r--src/corelib/thread/qreadwritelock.cpp4
-rw-r--r--src/corelib/thread/qreadwritelock.h5
-rw-r--r--src/corelib/thread/qreadwritelock_p.h4
-rw-r--r--src/corelib/thread/qrunnable.cpp107
-rw-r--r--src/corelib/thread/qrunnable.h72
-rw-r--r--src/corelib/thread/qsemaphore.cpp4
-rw-r--r--src/corelib/thread/qsemaphore.h5
-rw-r--r--src/corelib/thread/qthread.cpp22
-rw-r--r--src/corelib/thread/qthread.h5
-rw-r--r--src/corelib/thread/qthread_p.h15
-rw-r--r--src/corelib/thread/qthread_unix.cpp4
-rw-r--r--src/corelib/thread/qthread_win.cpp4
-rw-r--r--src/corelib/thread/qthreadpool.cpp651
-rw-r--r--src/corelib/thread/qthreadpool.h95
-rw-r--r--src/corelib/thread/qthreadpool_p.h107
-rw-r--r--src/corelib/thread/qthreadstorage.cpp16
-rw-r--r--src/corelib/thread/qthreadstorage.h5
-rw-r--r--src/corelib/thread/qwaitcondition.h5
-rw-r--r--src/corelib/thread/qwaitcondition.qdoc4
-rw-r--r--src/corelib/thread/qwaitcondition_unix.cpp4
-rw-r--r--src/corelib/thread/qwaitcondition_win.cpp6
-rw-r--r--src/corelib/thread/thread.pri9
37 files changed, 1586 insertions, 110 deletions
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp
index c2c9484cf6..5443d6e1b6 100644
--- a/src/corelib/thread/qatomic.cpp
+++ b/src/corelib/thread/qatomic.cpp
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/corelib/thread/qatomic.h b/src/corelib/thread/qatomic.h
index 07350ecfcd..b75ae94429 100644
--- a/src/corelib/thread/qatomic.h
+++ b/src/corelib/thread/qatomic.h
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -44,13 +44,12 @@
#ifndef QATOMIC_H
#define QATOMIC_H
-#include <QtCore/qoldbasicatomic.h>
+#include <QtCore/qbasicatomic.h>
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Core)
#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)
# pragma GCC diagnostic push
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
new file mode 100644
index 0000000000..47d690c13f
--- /dev/null
+++ b/src/corelib/thread/qbasicatomic.h
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Thiago Macieira <thiago@kde.org>
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBASICATOMIC_H
+#define QBASICATOMIC_H
+
+#include <QtCore/qglobal.h>
+
+#if defined(QT_MOC) || defined(QT_BUILD_QMAKE) || defined(QT_RCC) || defined(QT_UIC) || defined(QT_BOOTSTRAPPED)
+# include <QtCore/qatomic_bootstrap.h>
+#elif defined(Q_CC_MSVC)
+# include <QtCore/qatomic_msvc.h>
+#elif defined(__arm__) || defined(__TARGET_ARCH_ARM)
+# include <QtCore/qatomic_arm.h>
+#elif defined(__i386) || defined(__i386__)
+# include <QtCore/qatomic_i386.h>
+#elif defined(__ia64) || defined(__ia64__)
+# include "QtCore/qatomic_ia64.h"
+#elif defined(__mips) || defined(__mips__)
+# include "QtCore/qatomic_mips.h"
+#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64)
+# include <QtCore/qatomic_x86_64.h>
+#elif defined(Q_COMPILER_ATOMICS) && defined(Q_COMPILER_CONSTEXPR)
+# include <QtCore/qatomic_cxx11.h>
+#elif defined(Q_CC_GNU)
+# include <QtCore/qatomic_gcc.h>
+#else
+# define QT_OLD_ATOMICS
+#endif
+
+#ifdef QT_OLD_ATOMICS
+# include "QtCore/qoldbasicatomic.h"
+# undef QT_OLD_ATOMICS
+#else
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+#if 0
+#pragma qt_no_master_include
+#pragma qt_sync_stop_processing
+#endif
+
+// New atomics
+
+template <typename T>
+class QBasicAtomicInteger
+{
+public:
+ typedef QAtomicOps<T> Ops;
+ // static check that this is a valid integer
+ typedef char PermittedIntegerType[QAtomicIntegerTraits<T>::IsInteger ? 1 : -1];
+
+ typename Ops::Type _q_value;
+
+ // Non-atomic API
+ T load() const { return Ops::load(_q_value); }
+ void store(T newValue) { Ops::store(_q_value, newValue); }
+
+ // Atomic API, implemented in qatomic_XXX.h
+
+ T loadAcquire() { return Ops::loadAcquire(_q_value); }
+ void storeRelease(T newValue) { Ops::storeRelease(_q_value, newValue); }
+
+ static bool isReferenceCountingNative() { return Ops::isReferenceCountingNative(); }
+ static bool isReferenceCountingWaitFree() { return Ops::isReferenceCountingWaitFree(); }
+
+ bool ref() { return Ops::ref(_q_value); }
+ bool deref() { return Ops::deref(_q_value); }
+
+ static bool isTestAndSetNative() { return Ops::isTestAndSetNative(); }
+ static bool isTestAndSetWaitFree() { return Ops::isTestAndSetWaitFree(); }
+
+ bool testAndSetRelaxed(T expectedValue, T newValue)
+ { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue); }
+ bool testAndSetAcquire(T expectedValue, T newValue)
+ { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue); }
+ bool testAndSetRelease(T expectedValue, T newValue)
+ { return Ops::testAndSetRelease(_q_value, expectedValue, newValue); }
+ bool testAndSetOrdered(T expectedValue, T newValue)
+ { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue); }
+
+ static bool isFetchAndStoreNative() { return Ops::isFetchAndStoreNative(); }
+ static bool isFetchAndStoreWaitFree() { return Ops::isFetchAndStoreWaitFree(); }
+
+ T fetchAndStoreRelaxed(T newValue)
+ { return Ops::fetchAndStoreRelaxed(_q_value, newValue); }
+ T fetchAndStoreAcquire(T newValue)
+ { return Ops::fetchAndStoreAcquire(_q_value, newValue); }
+ T fetchAndStoreRelease(T newValue)
+ { return Ops::fetchAndStoreRelease(_q_value, newValue); }
+ T fetchAndStoreOrdered(T newValue)
+ { return Ops::fetchAndStoreOrdered(_q_value, newValue); }
+
+ static bool isFetchAndAddNative() { return Ops::isFetchAndAddNative(); }
+ static bool isFetchAndAddWaitFree() { return Ops::isFetchAndAddWaitFree(); }
+
+ T fetchAndAddRelaxed(T valueToAdd)
+ { return Ops::fetchAndAddRelaxed(_q_value, valueToAdd); }
+ T fetchAndAddAcquire(T valueToAdd)
+ { return Ops::fetchAndAddAcquire(_q_value, valueToAdd); }
+ T fetchAndAddRelease(T valueToAdd)
+ { return Ops::fetchAndAddRelease(_q_value, valueToAdd); }
+ T fetchAndAddOrdered(T valueToAdd)
+ { return Ops::fetchAndAddOrdered(_q_value, valueToAdd); }
+
+#if defined(Q_COMPILER_CONSTEXPR) && defined(Q_COMPILER_DEFAULT_DELETE_MEMBERS)
+ QBasicAtomicInteger() = default;
+ constexpr QBasicAtomicInteger(T value) : _q_value(value) {}
+ QBasicAtomicInteger(const QBasicAtomicInteger &) = delete;
+ QBasicAtomicInteger &operator=(const QBasicAtomicInteger &) = delete;
+ QBasicAtomicInteger &operator=(const QBasicAtomicInteger &) volatile = delete;
+#endif
+};
+typedef QBasicAtomicInteger<int> QBasicAtomicInt;
+
+template <typename X>
+class QBasicAtomicPointer
+{
+public:
+ typedef X *Type;
+ typedef QAtomicOps<Type> Ops;
+ typedef typename Ops::Type AtomicType;
+
+ AtomicType _q_value;
+
+ // Non-atomic API
+ Type load() const { return _q_value; }
+ void store(Type newValue) { _q_value = newValue; }
+
+ // Atomic API, implemented in qatomic_XXX.h
+ Type loadAcquire() { return Ops::loadAcquire(_q_value); }
+ void storeRelease(Type newValue) { Ops::storeRelease(_q_value, newValue); }
+
+ static bool isTestAndSetNative() { return Ops::isTestAndSetNative(); }
+ static bool isTestAndSetWaitFree() { return Ops::isTestAndSetWaitFree(); }
+
+ bool testAndSetRelaxed(Type expectedValue, Type newValue)
+ { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue); }
+ bool testAndSetAcquire(Type expectedValue, Type newValue)
+ { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue); }
+ bool testAndSetRelease(Type expectedValue, Type newValue)
+ { return Ops::testAndSetRelease(_q_value, expectedValue, newValue); }
+ bool testAndSetOrdered(Type expectedValue, Type newValue)
+ { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue); }
+
+ static bool isFetchAndStoreNative() { return Ops::isFetchAndStoreNative(); }
+ static bool isFetchAndStoreWaitFree() { return Ops::isFetchAndStoreWaitFree(); }
+
+ Type fetchAndStoreRelaxed(Type newValue)
+ { return Ops::fetchAndStoreRelaxed(_q_value, newValue); }
+ Type fetchAndStoreAcquire(Type newValue)
+ { return Ops::fetchAndStoreAcquire(_q_value, newValue); }
+ Type fetchAndStoreRelease(Type newValue)
+ { return Ops::fetchAndStoreRelease(_q_value, newValue); }
+ Type fetchAndStoreOrdered(Type newValue)
+ { return Ops::fetchAndStoreOrdered(_q_value, newValue); }
+
+ static bool isFetchAndAddNative() { return Ops::isFetchAndAddNative(); }
+ static bool isFetchAndAddWaitFree() { return Ops::isFetchAndAddWaitFree(); }
+
+ Type fetchAndAddRelaxed(qptrdiff valueToAdd)
+ { return Ops::fetchAndAddRelaxed(_q_value, valueToAdd); }
+ Type fetchAndAddAcquire(qptrdiff valueToAdd)
+ { return Ops::fetchAndAddAcquire(_q_value, valueToAdd); }
+ Type fetchAndAddRelease(qptrdiff valueToAdd)
+ { return Ops::fetchAndAddRelease(_q_value, valueToAdd); }
+ Type fetchAndAddOrdered(qptrdiff valueToAdd)
+ { return Ops::fetchAndAddOrdered(_q_value, valueToAdd); }
+
+#if defined(Q_COMPILER_CONSTEXPR) && defined(Q_COMPILER_DEFAULT_DELETE_MEMBERS)
+ QBasicAtomicPointer() = default;
+ constexpr QBasicAtomicPointer(Type value) : _q_value(value) {}
+ QBasicAtomicPointer(const QBasicAtomicPointer &) = delete;
+ QBasicAtomicPointer &operator=(const QBasicAtomicPointer &) = delete;
+ QBasicAtomicPointer &operator=(const QBasicAtomicPointer &) volatile = delete;
+#endif
+};
+
+#ifndef Q_BASIC_ATOMIC_INITIALIZER
+# define Q_BASIC_ATOMIC_INITIALIZER(a) { (a) }
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_OLD_ATOMICS
+
+
+#endif // QBASIC_ATOMIC
diff --git a/src/corelib/thread/qgenericatomic.h b/src/corelib/thread/qgenericatomic.h
new file mode 100644
index 0000000000..984ebed47b
--- /dev/null
+++ b/src/corelib/thread/qgenericatomic.h
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Thiago Macieira <thiago@kde.org>
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGENERICATOMIC_H
+#define QGENERICATOMIC_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+#if 0
+#pragma qt_sync_stop_processing
+#endif
+
+#ifdef Q_CC_GNU
+// lowercase is fine, we'll undef it below
+#define always_inline __attribute__((always_inline, gnu_inline))
+#else
+#define always_inline
+#endif
+
+template<typename T> struct QAtomicIntegerTraits { enum { IsInteger = 0 }; };
+
+template <typename T> struct QAtomicAdditiveType
+{
+ typedef T AdditiveT;
+ static const int AddScale = 1;
+};
+template <typename T> struct QAtomicAdditiveType<T *>
+{
+ typedef qptrdiff AdditiveT;
+ static const int AddScale = sizeof(T);
+};
+
+// not really atomic...
+template <typename BaseClass> struct QGenericAtomicOps
+{
+ template <typename T> struct AtomicType { typedef T Type; typedef T *PointerType; };
+
+ static void acquireMemoryFence() { BaseClass::orderedMemoryFence(); }
+ static void releaseMemoryFence() { BaseClass::orderedMemoryFence(); }
+ static void orderedMemoryFence() { }
+
+ template <typename T> static inline always_inline
+ T load(T &_q_value)
+ {
+ return _q_value;
+ }
+
+ template <typename T, typename X> static inline always_inline
+ void store(T &_q_value, X newValue)
+ {
+ _q_value = newValue;
+ }
+
+ template <typename T> static inline always_inline
+ T loadAcquire(T &_q_value)
+ {
+ T tmp = *static_cast<volatile T *>(&_q_value);
+ BaseClass::acquireMemoryFence();
+ return tmp;
+ }
+
+ template <typename T, typename X> static inline always_inline
+ void storeRelease(T &_q_value, X newValue)
+ {
+ BaseClass::releaseMemoryFence();
+ *static_cast<volatile T *>(&_q_value) = newValue;
+ }
+
+ static inline bool isReferenceCountingNative()
+ { return BaseClass::isFetchAndAddNative(); }
+ static inline bool isReferenceCountingWaitFree()
+ { return BaseClass::isFetchAndAddWaitFree(); }
+ template <typename T> static inline always_inline
+ bool ref(T &_q_value)
+ {
+ return BaseClass::fetchAndAddRelaxed(_q_value, 1) != T(-1);
+ }
+
+ template <typename T> static inline always_inline
+ bool deref(T &_q_value)
+ {
+ return BaseClass::fetchAndAddRelaxed(_q_value, -1) != 1;
+ }
+
+#if 0
+ // These functions have no default implementation
+ // Archictectures must implement them
+ static inline bool isTestAndSetNative();
+ static inline bool isTestAndSetWaitFree();
+ template <typename T, typename X> static inline
+ bool testAndSetRelaxed(T &_q_value, X expectedValue, X newValue);
+#endif
+
+ template <typename T, typename X> static inline always_inline
+ bool testAndSetAcquire(T &_q_value, X expectedValue, X newValue)
+ {
+ bool tmp = BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
+ BaseClass::acquireMemoryFence();
+ return tmp;
+ }
+
+ template <typename T, typename X> static inline always_inline
+ bool testAndSetRelease(T &_q_value, X expectedValue, X newValue)
+ {
+ BaseClass::releaseMemoryFence();
+ return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
+ }
+
+ template <typename T, typename X> static inline always_inline
+ bool testAndSetOrdered(T &_q_value, X expectedValue, X newValue)
+ {
+ BaseClass::orderedMemoryFence();
+ return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
+ }
+
+ static inline bool isFetchAndStoreNative() { return false; }
+ static inline bool isFetchAndStoreWaitFree() { return false; }
+
+ template <typename T, typename X> static inline always_inline
+ T fetchAndStoreRelaxed(T &_q_value, X newValue)
+ {
+ // implement fetchAndStore on top of testAndSet
+ Q_FOREVER {
+ register T tmp = load(_q_value);
+ if (BaseClass::testAndSetRelaxed(_q_value, tmp, newValue))
+ return tmp;
+ }
+ }
+
+ template <typename T, typename X> static inline always_inline
+ T fetchAndStoreAcquire(T &_q_value, X newValue)
+ {
+ T tmp = BaseClass::fetchAndStoreRelaxed(_q_value, newValue);
+ BaseClass::acquireMemoryFence();
+ return tmp;
+ }
+
+ template <typename T, typename X> static inline always_inline
+ T fetchAndStoreRelease(T &_q_value, X newValue)
+ {
+ BaseClass::releaseMemoryFence();
+ return BaseClass::fetchAndStoreRelaxed(_q_value, newValue);
+ }
+
+ template <typename T, typename X> static inline always_inline
+ T fetchAndStoreOrdered(T &_q_value, X newValue)
+ {
+ BaseClass::orderedMemoryFence();
+ return BaseClass::fetchAndStoreRelaxed(_q_value, newValue);
+ }
+
+ static inline bool isFetchAndAddNative() { return false; }
+ static inline bool isFetchAndAddWaitFree() { return false; }
+ template <typename T> static inline always_inline
+ T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd)
+ {
+ // implement fetchAndAdd on top of testAndSet
+ Q_FOREVER {
+ register T tmp = BaseClass::load(_q_value);
+ if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp + valueToAdd)))
+ return tmp;
+ }
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd)
+ {
+ T tmp = BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
+ BaseClass::acquireMemoryFence();
+ return tmp;
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd)
+ {
+ BaseClass::releaseMemoryFence();
+ return BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndAddOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd)
+ {
+ BaseClass::orderedMemoryFence();
+ return BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
+ }
+};
+
+#undef always_inline
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif // QGENERICATOMIC_H
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 6c8ed3b897..4a64feff0e 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h
index 1d7e591b7d..9a81b3d4bd 100644
--- a/src/corelib/thread/qmutex.h
+++ b/src/corelib/thread/qmutex.h
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -50,7 +50,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Core)
#if !defined(QT_NO_THREAD) && !defined(qdoc)
diff --git a/src/corelib/thread/qmutex_linux.cpp b/src/corelib/thread/qmutex_linux.cpp
index 9bb9c9061e..b1618f7fc9 100644
--- a/src/corelib/thread/qmutex_linux.cpp
+++ b/src/corelib/thread/qmutex_linux.cpp
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/corelib/thread/qmutex_mac.cpp b/src/corelib/thread/qmutex_mac.cpp
index 1a561aa5d5..ecd3442d91 100644
--- a/src/corelib/thread/qmutex_mac.cpp
+++ b/src/corelib/thread/qmutex_mac.cpp
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h
index 0cbc99adc6..3cf0938e94 100644
--- a/src/corelib/thread/qmutex_p.h
+++ b/src/corelib/thread/qmutex_p.h
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -118,8 +118,8 @@ public:
bool wakeup;
pthread_mutex_t mutex;
pthread_cond_t cond;
-#elif defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
- HANDLE event;
+#elif defined(Q_OS_WIN)
+ Qt::HANDLE event;
#endif
};
#endif //Q_OS_LINUX
diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp
index a426d958f2..0347d4b3da 100644
--- a/src/corelib/thread/qmutex_unix.cpp
+++ b/src/corelib/thread/qmutex_unix.cpp
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/corelib/thread/qmutex_win.cpp b/src/corelib/thread/qmutex_win.cpp
index b513b6e1ad..1fdf97b0d0 100644
--- a/src/corelib/thread/qmutex_win.cpp
+++ b/src/corelib/thread/qmutex_win.cpp
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,15 +34,15 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <qt_windows.h>
-
#include "qmutex.h"
#include <qatomic.h>
#include "qmutex_p.h"
+#include <qt_windows.h>
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/thread/qmutexpool.cpp b/src/corelib/thread/qmutexpool.cpp
index 6be5e092d7..b102770d23 100644
--- a/src/corelib/thread/qmutexpool.cpp
+++ b/src/corelib/thread/qmutexpool.cpp
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/corelib/thread/qmutexpool_p.h b/src/corelib/thread/qmutexpool_p.h
index 90b89f9a17..ce55a40bb8 100644
--- a/src/corelib/thread/qmutexpool_p.h
+++ b/src/corelib/thread/qmutexpool_p.h
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/corelib/thread/qoldbasicatomic.h b/src/corelib/thread/qoldbasicatomic.h
index 2f952c9e0a..a1985793ed 100644
--- a/src/corelib/thread/qoldbasicatomic.h
+++ b/src/corelib/thread/qoldbasicatomic.h
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,12 +34,13 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
-#ifndef QBASICATOMIC_H
-#define QBASICATOMIC_H
+#ifndef QOLDBASICATOMIC_H
+#define QOLDBASICATOMIC_H
#include <QtCore/qglobal.h>
@@ -48,7 +48,11 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Core)
+
+#if 0
+#pragma qt_no_master_include
+#pragma qt_sync_stop_processing
+#endif
class Q_CORE_EXPORT QBasicAtomicInt
{
@@ -166,10 +170,6 @@ public:
QT_END_NAMESPACE
QT_END_HEADER
-#if defined(QT_MOC) || defined(QT_BUILD_QMAKE) || defined(QT_RCC) || defined(QT_UIC) || defined(QT_BOOTSTRAPPED)
-# include <QtCore/qatomic_bootstrap.h>
-#else
# include <QtCore/qatomic_arch.h>
-#endif
#endif // QBASIC_ATOMIC
diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h
index 14a29c7edf..4f8378f496 100644
--- a/src/corelib/thread/qorderedmutexlocker_p.h
+++ b/src/corelib/thread/qorderedmutexlocker_p.h
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp
index 54926111d5..519bae9fa6 100644
--- a/src/corelib/thread/qreadwritelock.cpp
+++ b/src/corelib/thread/qreadwritelock.cpp
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/corelib/thread/qreadwritelock.h b/src/corelib/thread/qreadwritelock.h
index cdbd7894a1..092352f611 100644
--- a/src/corelib/thread/qreadwritelock.h
+++ b/src/corelib/thread/qreadwritelock.h
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -49,7 +49,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Core)
#ifndef QT_NO_THREAD
diff --git a/src/corelib/thread/qreadwritelock_p.h b/src/corelib/thread/qreadwritelock_p.h
index 125245bb4a..85e767ac12 100644
--- a/src/corelib/thread/qreadwritelock_p.h
+++ b/src/corelib/thread/qreadwritelock_p.h
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/corelib/thread/qrunnable.cpp b/src/corelib/thread/qrunnable.cpp
new file mode 100644
index 0000000000..933a5b922c
--- /dev/null
+++ b/src/corelib/thread/qrunnable.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QRunnable
+ \since 4.4
+ \brief The QRunnable class is the base class for all runnable objects.
+
+ \ingroup thread
+
+ The QRunnable class is an interface for representing a task or
+ piece of code that needs to be executed, represented by your
+ reimplementation of the run() function.
+
+ You can use QThreadPool to execute your code in a separate
+ thread. QThreadPool deletes the QRunnable automatically if
+ autoDelete() returns true (the default). Use setAutoDelete() to
+ change the auto-deletion flag.
+
+ QThreadPool supports executing the same QRunnable more than once
+ by calling QThreadPool::tryStart(this) from within the run() function.
+ If autoDelete is enabled the QRunnable will be deleted when
+ the last thread exits the run function. Calling QThreadPool::start()
+ multiple times with the same QRunnable when autoDelete is enabled
+ creates a race condition and is not recommended.
+
+ \sa QThreadPool
+*/
+
+/*! \fn QRunnable::run()
+ Implement this pure virtual function in your subclass.
+*/
+
+/*! \fn QRunnable::QRunnable()
+ Constructs a QRunnable. Auto-deletion is enabled by default.
+
+ \sa autoDelete(), setAutoDelete()
+*/
+
+/*! \fn QRunnable::~QRunnable()
+ QRunnable virtual destructor.
+*/
+
+/*! \fn bool QRunnable::autoDelete() const
+
+ Returns true is auto-deletion is enabled; false otherwise.
+
+ If auto-deletion is enabled, QThreadPool will automatically delete
+ this runnable after calling run(); otherwise, ownership remains
+ with the application programmer.
+
+ \sa setAutoDelete(), QThreadPool
+*/
+
+/*! \fn bool QRunnable::setAutoDelete(bool autoDelete)
+
+ Enables auto-deletion if \a autoDelete is true; otherwise
+ auto-deletion is disabled.
+
+ If auto-deletion is enabled, QThreadPool will automatically delete
+ this runnable after calling run(); otherwise, ownership remains
+ with the application programmer.
+
+ Note that this flag must be set before calling
+ QThreadPool::start(). Calling this function after
+ QThreadPool::start() results in undefined behavior.
+
+ \sa autoDelete(), QThreadPool
+*/
diff --git a/src/corelib/thread/qrunnable.h b/src/corelib/thread/qrunnable.h
new file mode 100644
index 0000000000..11d5c0146e
--- /dev/null
+++ b/src/corelib/thread/qrunnable.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QRUNNABLE_H
+#define QRUNNABLE_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+
+class QRunnable
+{
+ int ref;
+
+ friend class QThreadPool;
+ friend class QThreadPoolPrivate;
+ friend class QThreadPoolThread;
+
+public:
+ virtual void run() = 0;
+
+ QRunnable() : ref(0) { }
+ virtual ~QRunnable() { }
+
+ bool autoDelete() const { return ref != -1; }
+ void setAutoDelete(bool _autoDelete) { ref = _autoDelete ? 0 : -1; }
+};
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp
index 12539a794d..52f5a1d699 100644
--- a/src/corelib/thread/qsemaphore.cpp
+++ b/src/corelib/thread/qsemaphore.cpp
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/corelib/thread/qsemaphore.h b/src/corelib/thread/qsemaphore.h
index 4790a84bb6..c1d27bbde4 100644
--- a/src/corelib/thread/qsemaphore.h
+++ b/src/corelib/thread/qsemaphore.h
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -48,7 +48,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Core)
#ifndef QT_NO_THREAD
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 9d48c4dbe5..be0a98d3b5 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -52,24 +52,6 @@
#include "qthread_p.h"
#include "private/qcoreapplication_p.h"
-/*
-#ifdef Q_OS_WIN32
-# include "qt_windows.h"
-#else
-# include <unistd.h>
-# include <netinet/in.h>
-# include <sys/utsname.h>
-# include <sys/socket.h>
-*/
-/*
-# elif defined(Q_OS_HPUX)
-# include <sys/pstat.h>
-# elif defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) || defined(Q_OS_MAC)
-# include <sys/sysctl.h>
-# endif
-#endif
-*/
-
QT_BEGIN_NAMESPACE
/*
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h
index 597e29546a..719f4afbbb 100644
--- a/src/corelib/thread/qthread.h
+++ b/src/corelib/thread/qthread.h
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -50,7 +50,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Core)
class QThreadData;
class QThreadPrivate;
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index 094c9b0daf..d8374e9805 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -167,16 +167,13 @@ public:
#endif // Q_OS_UNIX
-#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
- HANDLE handle;
- unsigned int id;
- int waiters;
-
+#ifdef Q_OS_WIN
static unsigned int __stdcall start(void *);
static void finish(void *, bool lockAnyway=true);
-#endif // Q_OS_WIN32
-#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+ Qt::HANDLE handle;
+ unsigned int id;
+ int waiters;
bool terminationEnabled, terminatePending;
# endif
QThreadData *data;
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 672b7cb976..9ce951cf3b 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index 3184b18471..bdee6d6b7c 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp
new file mode 100644
index 0000000000..af8c99197e
--- /dev/null
+++ b/src/corelib/thread/qthreadpool.cpp
@@ -0,0 +1,651 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qthreadpool.h"
+#include "qthreadpool_p.h"
+#include "qelapsedtimer.h"
+
+#ifndef QT_NO_THREAD
+
+QT_BEGIN_NAMESPACE
+
+inline bool operator<(int priority, const QPair<QRunnable *, int> &p)
+{
+ return p.second < priority;
+}
+inline bool operator<(const QPair<QRunnable *, int> &p, int priority)
+{
+ return priority < p.second;
+}
+
+Q_GLOBAL_STATIC(QThreadPool, theInstance)
+
+/*
+ QThread wrapper, provides synchronizitaion against a ThreadPool
+*/
+class QThreadPoolThread : public QThread
+{
+public:
+ QThreadPoolThread(QThreadPoolPrivate *manager);
+ void run();
+ void registerTheadInactive();
+
+ QThreadPoolPrivate *manager;
+ QRunnable *runnable;
+};
+
+/*
+ QThreadPool private class.
+*/
+
+
+/*!\internal
+
+*/
+QThreadPoolThread::QThreadPoolThread(QThreadPoolPrivate *manager)
+ :manager(manager), runnable(0)
+{ }
+
+/* \internal
+
+*/
+void QThreadPoolThread::run()
+{
+ QMutexLocker locker(&manager->mutex);
+ for(;;) {
+ QRunnable *r = runnable;
+ runnable = 0;
+
+ do {
+ if (r) {
+ const bool autoDelete = r->autoDelete();
+
+
+ // run the task
+ locker.unlock();
+#ifndef QT_NO_EXCEPTIONS
+ try {
+#endif
+ r->run();
+#ifndef QT_NO_EXCEPTIONS
+ } catch (...) {
+ qWarning("Qt Concurrent has caught an exception thrown from a worker thread.\n"
+ "This is not supported, exceptions thrown in worker threads must be\n"
+ "caught before control returns to Qt Concurrent.");
+ registerTheadInactive();
+ throw;
+ }
+#endif
+ locker.relock();
+
+ if (autoDelete && !--r->ref)
+ delete r;
+ }
+
+ // if too many threads are active, expire this thread
+ if (manager->tooManyThreadsActive())
+ break;
+
+ r = !manager->queue.isEmpty() ? manager->queue.takeFirst().first : 0;
+ } while (r != 0);
+
+ if (manager->isExiting) {
+ registerTheadInactive();
+ break;
+ }
+
+ // if too many threads are active, expire this thread
+ bool expired = manager->tooManyThreadsActive();
+ if (!expired) {
+ ++manager->waitingThreads;
+ registerTheadInactive();
+ // wait for work, exiting after the expiry timeout is reached
+ expired = !manager->runnableReady.wait(locker.mutex(), manager->expiryTimeout);
+ ++manager->activeThreads;
+
+ if (expired)
+ --manager->waitingThreads;
+ }
+ if (expired) {
+ manager->expiredThreads.enqueue(this);
+ registerTheadInactive();
+ break;
+ }
+ }
+}
+
+void QThreadPoolThread::registerTheadInactive()
+{
+ if (--manager->activeThreads == 0)
+ manager->noActiveThreads.wakeAll();
+}
+
+
+/* \internal
+
+*/
+QThreadPoolPrivate:: QThreadPoolPrivate()
+ : isExiting(false),
+ expiryTimeout(30000),
+ maxThreadCount(qAbs(QThread::idealThreadCount())),
+ reservedThreads(0),
+ waitingThreads(0),
+ activeThreads(0)
+{ }
+
+bool QThreadPoolPrivate::tryStart(QRunnable *task)
+{
+ if (allThreads.isEmpty()) {
+ // always create at least one thread
+ startThread(task);
+ return true;
+ }
+
+ // can't do anything if we're over the limit
+ if (activeThreadCount() >= maxThreadCount)
+ return false;
+
+ if (waitingThreads > 0) {
+ // recycle an available thread
+ --waitingThreads;
+ enqueueTask(task);
+ return true;
+ }
+
+ if (!expiredThreads.isEmpty()) {
+ // restart an expired thread
+ QThreadPoolThread *thread = expiredThreads.dequeue();
+ Q_ASSERT(thread->runnable == 0);
+
+ ++activeThreads;
+
+ if (task->autoDelete())
+ ++task->ref;
+ thread->runnable = task;
+ thread->start();
+ return true;
+ }
+
+ // start a new thread
+ startThread(task);
+ return true;
+}
+
+void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority)
+{
+ if (runnable->autoDelete())
+ ++runnable->ref;
+
+ // put it on the queue
+ QList<QPair<QRunnable *, int> >::iterator at =
+ qUpperBound(queue.begin(), queue.end(), priority);
+ queue.insert(at, qMakePair(runnable, priority));
+ runnableReady.wakeOne();
+}
+
+int QThreadPoolPrivate::activeThreadCount() const
+{
+ // To improve scalability this function is called without holding
+ // the mutex lock -- keep it thread-safe.
+ return (allThreads.count()
+ - expiredThreads.count()
+ - waitingThreads
+ + reservedThreads);
+}
+
+void QThreadPoolPrivate::tryToStartMoreThreads()
+{
+ // try to push tasks on the queue to any available threads
+ while (!queue.isEmpty() && tryStart(queue.first().first))
+ queue.removeFirst();
+}
+
+bool QThreadPoolPrivate::tooManyThreadsActive() const
+{
+ const int activeThreadCount = this->activeThreadCount();
+ return activeThreadCount > maxThreadCount && (activeThreadCount - reservedThreads) > 1;
+}
+
+/*! \internal
+
+*/
+void QThreadPoolPrivate::startThread(QRunnable *runnable)
+{
+ QScopedPointer <QThreadPoolThread> thread(new QThreadPoolThread(this));
+ thread->setObjectName(QLatin1String("Thread (pooled)"));
+ allThreads.insert(thread.data());
+ ++activeThreads;
+
+ if (runnable->autoDelete())
+ ++runnable->ref;
+ thread->runnable = runnable;
+ thread.take()->start();
+}
+
+/*! \internal
+ Makes all threads exit, waits for each tread to exit and deletes it.
+*/
+void QThreadPoolPrivate::reset()
+{
+ QMutexLocker locker(&mutex);
+ isExiting = true;
+ runnableReady.wakeAll();
+
+ do {
+ // make a copy of the set so that we can iterate without the lock
+ QSet<QThreadPoolThread *> allThreadsCopy = allThreads;
+ allThreads.clear();
+ locker.unlock();
+
+ foreach (QThreadPoolThread *thread, allThreadsCopy) {
+ thread->wait();
+ delete thread;
+ }
+
+ locker.relock();
+ // repeat until all newly arrived threads have also completed
+ } while (!allThreads.isEmpty());
+
+ waitingThreads = 0;
+ expiredThreads.clear();
+
+ isExiting = false;
+}
+
+bool QThreadPoolPrivate::waitForDone(int msecs)
+{
+ QMutexLocker locker(&mutex);
+ if (msecs < 0) {
+ while (!(queue.isEmpty() && activeThreads == 0))
+ noActiveThreads.wait(locker.mutex());
+ } else {
+ QElapsedTimer timer;
+ timer.start();
+ int t;
+ while (!(queue.isEmpty() && activeThreads == 0) &&
+ ((t = msecs - timer.elapsed()) > 0))
+ noActiveThreads.wait(locker.mutex(), t);
+ }
+ return queue.isEmpty() && activeThreads == 0;
+}
+
+/*! \internal
+ Pulls a runnable from the front queue and runs it in the current thread. Blocks
+ until the runnable has completed. Returns true if a runnable was found.
+*/
+bool QThreadPoolPrivate::startFrontRunnable()
+{
+ QMutexLocker locker(&mutex);
+ if (queue.isEmpty())
+ return false;
+
+ QRunnable *runnable = queue.takeFirst().first;
+ const bool autoDelete = runnable->autoDelete();
+ bool del = autoDelete && !--runnable->ref;
+
+ locker.unlock();
+ runnable->run();
+ locker.relock();
+
+ if (del) {
+ delete runnable;
+ }
+
+ return true;
+}
+
+/*! \internal
+ Seaches for \a runnable in the queue, removes it from the queue and
+ runs it if found. This functon does not return until the runnable
+ has completed.
+*/
+void QThreadPoolPrivate::stealRunnable(QRunnable *runnable)
+{
+ if (runnable == 0 || queue.isEmpty())
+ return;
+ bool found = false;
+ {
+ QMutexLocker locker(&mutex);
+ QList<QPair<QRunnable *, int> >::iterator it = queue.begin();
+ QList<QPair<QRunnable *, int> >::iterator end = queue.end();
+
+ while (it != end) {
+ if (it->first == runnable) {
+ found = true;
+ queue.erase(it);
+ break;
+ }
+ ++it;
+ }
+ }
+
+ if (!found)
+ return;
+
+ const bool autoDelete = runnable->autoDelete();
+ bool del = autoDelete && !--runnable->ref;
+
+ runnable->run();
+
+ if (del) {
+ delete runnable;
+ }
+}
+
+/*!
+ \class QThreadPool
+ \brief The QThreadPool class manages a collection of QThreads.
+ \since 4.4
+ \threadsafe
+
+ \ingroup thread
+
+ QThreadPool manages and recyles individual QThread objects to help reduce
+ thread creation costs in programs that use threads. Each Qt application
+ has one global QThreadPool object, which can be accessed by calling
+ globalInstance().
+
+ To use one of the QThreadPool threads, subclass QRunnable and implement
+ the run() virtual function. Then create an object of that class and pass
+ it to QThreadPool::start().
+
+ \snippet doc/src/snippets/code/src_corelib_concurrent_qthreadpool.cpp 0
+
+ QThreadPool deletes the QRunnable automatically by default. Use
+ QRunnable::setAutoDelete() to change the auto-deletion flag.
+
+ QThreadPool supports executing the same QRunnable more than once
+ by calling tryStart(this) from within QRunnable::run().
+ If autoDelete is enabled the QRunnable will be deleted when
+ the last thread exits the run function. Calling start()
+ multiple times with the same QRunnable when autoDelete is enabled
+ creates a race condition and is not recommended.
+
+ Threads that are unused for a certain amount of time will expire. The
+ default expiry timeout is 30000 milliseconds (30 seconds). This can be
+ changed using setExpiryTimeout(). Setting a negative expiry timeout
+ disables the expiry mechanism.
+
+ Call maxThreadCount() to query the maximum number of threads to be used.
+ If needed, you can change the limit with setMaxThreadCount(). The default
+ maxThreadCount() is QThread::idealThreadCount(). The activeThreadCount()
+ function returns the number of threads currently doing work.
+
+ The reserveThread() function reserves a thread for external
+ use. Use releaseThread() when your are done with the thread, so
+ that it may be reused. Essentially, these functions temporarily
+ increase or reduce the active thread count and are useful when
+ implementing time-consuming operations that are not visible to the
+ QThreadPool.
+
+ Note that QThreadPool is a low-level class for managing threads, see
+ QtConcurrent::run() or the other
+ \l {Concurrent Programming}{Qt Concurrent} APIs for higher
+ level alternatives.
+
+ \sa QRunnable
+*/
+
+/*!
+ Constructs a thread pool with the given \a parent.
+*/
+QThreadPool::QThreadPool(QObject *parent)
+ : QObject(*new QThreadPoolPrivate, parent)
+{ }
+
+/*!
+ Destroys the QThreadPool.
+ This function will block until all runnables have been completed.
+*/
+QThreadPool::~QThreadPool()
+{
+ d_func()->waitForDone();
+ d_func()->reset();
+}
+
+/*!
+ Returns the global QThreadPool instance.
+*/
+QThreadPool *QThreadPool::globalInstance()
+{
+ return theInstance();
+}
+
+/*!
+ Reserves a thread and uses it to run \a runnable, unless this thread will
+ make the current thread count exceed maxThreadCount(). In that case,
+ \a runnable is added to a run queue instead. The \a priority argument can
+ be used to control the run queue's order of execution.
+
+ Note that the thread pool takes ownership of the \a runnable if
+ \l{QRunnable::autoDelete()}{runnable->autoDelete()} returns true,
+ and the \a runnable will be deleted automatically by the thread
+ pool after the \l{QRunnable::run()}{runnable->run()} returns. If
+ \l{QRunnable::autoDelete()}{runnable->autoDelete()} returns false,
+ ownership of \a runnable remains with the caller. Note that
+ changing the auto-deletion on \a runnable after calling this
+ functions results in undefined behavior.
+*/
+void QThreadPool::start(QRunnable *runnable, int priority)
+{
+ if (!runnable)
+ return;
+
+ Q_D(QThreadPool);
+ QMutexLocker locker(&d->mutex);
+ if (!d->tryStart(runnable))
+ d->enqueueTask(runnable, priority);
+}
+
+/*!
+ Attempts to reserve a thread to run \a runnable.
+
+ If no threads are available at the time of calling, then this function
+ does nothing and returns false. Otherwise, \a runnable is run immediately
+ using one available thread and this function returns true.
+
+ Note that the thread pool takes ownership of the \a runnable if
+ \l{QRunnable::autoDelete()}{runnable->autoDelete()} returns true,
+ and the \a runnable will be deleted automatically by the thread
+ pool after the \l{QRunnable::run()}{runnable->run()} returns. If
+ \l{QRunnable::autoDelete()}{runnable->autoDelete()} returns false,
+ ownership of \a runnable remains with the caller. Note that
+ changing the auto-deletion on \a runnable after calling this
+ function results in undefined behavior.
+*/
+bool QThreadPool::tryStart(QRunnable *runnable)
+{
+ if (!runnable)
+ return false;
+
+ Q_D(QThreadPool);
+
+ // To improve scalability perform a check on the thread count
+ // before locking the mutex.
+ if (d->allThreads.isEmpty() == false && d->activeThreadCount() >= d->maxThreadCount)
+ return false;
+
+ QMutexLocker locker(&d->mutex);
+ return d->tryStart(runnable);
+}
+
+/*! \property QThreadPool::expiryTimeout
+
+ Threads that are unused for \a expiryTimeout milliseconds are considered
+ to have expired and will exit. Such threads will be restarted as needed.
+ The default \a expiryTimeout is 30000 milliseconds (30 seconds). If
+ \a expiryTimeout is negative, newly created threads will not expire, e.g.,
+ they will not exit until the thread pool is destroyed.
+
+ Note that setting \a expiryTimeout has no effect on already running
+ threads. Only newly created threads will use the new \a expiryTimeout.
+ We recommend setting the \a expiryTimeout immediately after creating the
+ thread pool, but before calling start().
+*/
+
+int QThreadPool::expiryTimeout() const
+{
+ Q_D(const QThreadPool);
+ return d->expiryTimeout;
+}
+
+void QThreadPool::setExpiryTimeout(int expiryTimeout)
+{
+ Q_D(QThreadPool);
+ if (d->expiryTimeout == expiryTimeout)
+ return;
+ d->expiryTimeout = expiryTimeout;
+}
+
+/*! \property QThreadPool::maxThreadCount
+
+ This property represents the maximum number of threads used by the thread
+ pool.
+
+ \note The thread pool will always use at least 1 thread, even if
+ \a maxThreadCount limit is zero or negative.
+
+ The default \a maxThreadCount is QThread::idealThreadCount().
+*/
+
+int QThreadPool::maxThreadCount() const
+{
+ Q_D(const QThreadPool);
+ return d->maxThreadCount;
+}
+
+void QThreadPool::setMaxThreadCount(int maxThreadCount)
+{
+ Q_D(QThreadPool);
+ QMutexLocker locker(&d->mutex);
+
+ if (maxThreadCount == d->maxThreadCount)
+ return;
+
+ d->maxThreadCount = maxThreadCount;
+ d->tryToStartMoreThreads();
+}
+
+/*! \property QThreadPool::activeThreadCount
+
+ This property represents the number of active threads in the thread pool.
+
+ \note It is possible for this function to return a value that is greater
+ than maxThreadCount(). See reserveThread() for more details.
+
+ \sa reserveThread(), releaseThread()
+*/
+
+int QThreadPool::activeThreadCount() const
+{
+ Q_D(const QThreadPool);
+ return d->activeThreadCount();
+}
+
+/*!
+ Reserves one thread, disregarding activeThreadCount() and maxThreadCount().
+
+ Once you are done with the thread, call releaseThread() to allow it to be
+ reused.
+
+ \note This function will always increase the number of active threads.
+ This means that by using this function, it is possible for
+ activeThreadCount() to return a value greater than maxThreadCount() .
+
+ \sa releaseThread()
+ */
+void QThreadPool::reserveThread()
+{
+ Q_D(QThreadPool);
+ QMutexLocker locker(&d->mutex);
+ ++d->reservedThreads;
+}
+
+/*!
+ Releases a thread previously reserved by a call to reserveThread().
+
+ \note Calling this function without previously reserving a thread
+ temporarily increases maxThreadCount(). This is useful when a
+ thread goes to sleep waiting for more work, allowing other threads
+ to continue. Be sure to call reserveThread() when done waiting, so
+ that the thread pool can correctly maintain the
+ activeThreadCount().
+
+ \sa reserveThread()
+*/
+void QThreadPool::releaseThread()
+{
+ Q_D(QThreadPool);
+ QMutexLocker locker(&d->mutex);
+ --d->reservedThreads;
+ d->tryToStartMoreThreads();
+}
+
+/*!
+ Waits for each thread to exit and removes all threads from the thread pool.
+*/
+void QThreadPool::waitForDone()
+{
+ Q_D(QThreadPool);
+ d->waitForDone();
+ d->reset();
+}
+
+/*!
+ \overload waitForDone()
+ \since 4.8
+
+ Waits up to \a msecs milliseconds for all threads to exit and removes all
+ threads from the thread pool. Returns true if all threads were removed;
+ otherwise it returns false.
+*/
+bool QThreadPool::waitForDone(int msecs)
+{
+ Q_D(QThreadPool);
+ bool rc = d->waitForDone(msecs);
+ if (rc)
+ d->reset();
+ return rc;
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/corelib/thread/qthreadpool.h b/src/corelib/thread/qthreadpool.h
new file mode 100644
index 0000000000..9fc023c56d
--- /dev/null
+++ b/src/corelib/thread/qthreadpool.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTHREADPOOL_H
+#define QTHREADPOOL_H
+
+#include <QtCore/qglobal.h>
+
+#include <QtCore/qthread.h>
+#include <QtCore/qrunnable.h>
+
+#ifndef QT_NO_THREAD
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+
+class QThreadPoolPrivate;
+class Q_CORE_EXPORT QThreadPool : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QThreadPool)
+ Q_PROPERTY(int expiryTimeout READ expiryTimeout WRITE setExpiryTimeout)
+ Q_PROPERTY(int maxThreadCount READ maxThreadCount WRITE setMaxThreadCount)
+ Q_PROPERTY(int activeThreadCount READ activeThreadCount)
+ friend class QFutureInterfaceBase;
+
+public:
+ QThreadPool(QObject *parent = 0);
+ ~QThreadPool();
+
+ static QThreadPool *globalInstance();
+
+ void start(QRunnable *runnable, int priority = 0);
+ bool tryStart(QRunnable *runnable);
+
+ int expiryTimeout() const;
+ void setExpiryTimeout(int expiryTimeout);
+
+ int maxThreadCount() const;
+ void setMaxThreadCount(int maxThreadCount);
+
+ int activeThreadCount() const;
+
+ void reserveThread();
+ void releaseThread();
+
+ void waitForDone();
+ bool waitForDone(int msecs);
+};
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif // QT_NO_THREAD
+
+#endif
diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h
new file mode 100644
index 0000000000..9a7c09695f
--- /dev/null
+++ b/src/corelib/thread/qthreadpool_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTHREADPOOL_P_H
+#define QTHREADPOOL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#include "QtCore/qmutex.h"
+#include "QtCore/qwaitcondition.h"
+#include "QtCore/qset.h"
+#include "QtCore/qqueue.h"
+#include "private/qobject_p.h"
+
+#ifndef QT_NO_THREAD
+
+QT_BEGIN_NAMESPACE
+
+class QThreadPoolThread;
+class Q_CORE_EXPORT QThreadPoolPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QThreadPool)
+ friend class QThreadPoolThread;
+
+public:
+ QThreadPoolPrivate();
+
+ bool tryStart(QRunnable *task);
+ void enqueueTask(QRunnable *task, int priority = 0);
+ int activeThreadCount() const;
+
+ void tryToStartMoreThreads();
+ bool tooManyThreadsActive() const;
+
+ void startThread(QRunnable *runnable = 0);
+ void reset();
+ bool waitForDone(int msecs = -1);
+ bool startFrontRunnable();
+ void stealRunnable(QRunnable *);
+
+ mutable QMutex mutex;
+ QWaitCondition runnableReady;
+ QSet<QThreadPoolThread *> allThreads;
+ QQueue<QThreadPoolThread *> expiredThreads;
+ QList<QPair<QRunnable *, int> > queue;
+ QWaitCondition noActiveThreads;
+
+ bool isExiting;
+ int expiryTimeout;
+ int maxThreadCount;
+ int reservedThreads;
+ int waitingThreads;
+ int activeThreads;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_THREAD
+#endif
diff --git a/src/corelib/thread/qthreadstorage.cpp b/src/corelib/thread/qthreadstorage.cpp
index 6dba8d670e..1dfa3305bc 100644
--- a/src/corelib/thread/qthreadstorage.cpp
+++ b/src/corelib/thread/qthreadstorage.cpp
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -71,13 +71,13 @@ void qtsDebug(const char *fmt, ...)
# define DEBUG_MSG if(false)qDebug
#endif
-Q_GLOBAL_STATIC(QMutex, mutex)
+static QBasicMutex destructorsMutex;
typedef QVector<void (*)(void *)> DestructorMap;
Q_GLOBAL_STATIC(DestructorMap, destructors)
QThreadStorageData::QThreadStorageData(void (*func)(void *))
{
- QMutexLocker locker(mutex());
+ QMutexLocker locker(&destructorsMutex);
DestructorMap *destr = destructors();
if (!destr) {
/*
@@ -109,7 +109,7 @@ QThreadStorageData::QThreadStorageData(void (*func)(void *))
QThreadStorageData::~QThreadStorageData()
{
DEBUG_MSG("QThreadStorageData: Released id %d", id);
- QMutexLocker locker(mutex());
+ QMutexLocker locker(&destructorsMutex);
if (destructors())
(*destructors())[id] = 0;
}
@@ -153,7 +153,7 @@ void **QThreadStorageData::set(void *p)
value,
data->thread);
- QMutexLocker locker(mutex());
+ QMutexLocker locker(&destructorsMutex);
DestructorMap *destr = destructors();
void (*destructor)(void *) = destr ? destr->value(id) : 0;
locker.unlock();
@@ -174,7 +174,7 @@ void **QThreadStorageData::set(void *p)
void QThreadStorageData::finish(void **p)
{
QVector<void *> *tls = reinterpret_cast<QVector<void *> *>(p);
- if (!tls || tls->isEmpty() || !mutex())
+ if (!tls || tls->isEmpty() || !destructors())
return; // nothing to do
DEBUG_MSG("QThreadStorageData: Destroying storage for thread %p", QThread::currentThread());
@@ -190,7 +190,7 @@ void QThreadStorageData::finish(void **p)
continue;
}
- QMutexLocker locker(mutex());
+ QMutexLocker locker(&destructorsMutex);
void (*destructor)(void *) = destructors()->value(i);
locker.unlock();
diff --git a/src/corelib/thread/qthreadstorage.h b/src/corelib/thread/qthreadstorage.h
index 790f9a51ef..706d4d0e86 100644
--- a/src/corelib/thread/qthreadstorage.h
+++ b/src/corelib/thread/qthreadstorage.h
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -50,7 +50,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Core)
class Q_CORE_EXPORT QThreadStorageData
{
diff --git a/src/corelib/thread/qwaitcondition.h b/src/corelib/thread/qwaitcondition.h
index 7d4eb684ee..f6e41aef4e 100644
--- a/src/corelib/thread/qwaitcondition.h
+++ b/src/corelib/thread/qwaitcondition.h
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -50,7 +50,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Core)
#ifndef QT_NO_THREAD
diff --git a/src/corelib/thread/qwaitcondition.qdoc b/src/corelib/thread/qwaitcondition.qdoc
index f079e5a6ba..7b861f8f7a 100644
--- a/src/corelib/thread/qwaitcondition.qdoc
+++ b/src/corelib/thread/qwaitcondition.qdoc
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the documentation of the Qt Toolkit.
**
@@ -21,6 +20,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/corelib/thread/qwaitcondition_unix.cpp b/src/corelib/thread/qwaitcondition_unix.cpp
index 91aea010d9..5641eba80a 100644
--- a/src/corelib/thread/qwaitcondition_unix.cpp
+++ b/src/corelib/thread/qwaitcondition_unix.cpp
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp
index 0106dbf13a..3528d6a0ff 100644
--- a/src/corelib/thread/qwaitcondition_win.cpp
+++ b/src/corelib/thread/qwaitcondition_win.cpp
@@ -1,8 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
@@ -35,6 +34,7 @@
**
**
**
+**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -45,13 +45,13 @@
#include "qreadwritelock.h"
#include "qlist.h"
#include "qalgorithms.h"
-#include "qt_windows.h"
#ifndef QT_NO_THREAD
#define Q_MUTEX_T void*
#include <private/qmutex_p.h>
#include <private/qreadwritelock_p.h>
+#include <qt_windows.h>
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/thread/thread.pri b/src/corelib/thread/thread.pri
index 974e086684..1eefa60d50 100644
--- a/src/corelib/thread/thread.pri
+++ b/src/corelib/thread/thread.pri
@@ -2,12 +2,16 @@
# public headers
HEADERS += thread/qmutex.h \
+ thread/qrunnable.h \
thread/qreadwritelock.h \
thread/qsemaphore.h \
thread/qthread.h \
+ thread/qthreadpool.h \
thread/qthreadstorage.h \
thread/qwaitcondition.h \
thread/qatomic.h \
+ thread/qbasicatomic.h \
+ thread/qgenericatomic.h \
thread/qoldbasicatomic.h
# private headers
@@ -15,14 +19,17 @@ HEADERS += thread/qmutex_p.h \
thread/qmutexpool_p.h \
thread/qorderedmutexlocker_p.h \
thread/qreadwritelock_p.h \
- thread/qthread_p.h
+ thread/qthread_p.h \
+ thread/qthreadpool_p.h
SOURCES += thread/qatomic.cpp \
thread/qmutex.cpp \
thread/qreadwritelock.cpp \
+ thread/qrunnable.cpp \
thread/qmutexpool.cpp \
thread/qsemaphore.cpp \
thread/qthread.cpp \
+ thread/qthreadpool.cpp \
thread/qthreadstorage.cpp
unix:SOURCES += thread/qthread_unix.cpp \