summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qfuture.h25
-rw-r--r--src/corelib/thread/qfutureinterface.h10
-rw-r--r--src/corelib/thread/qfutureinterface_p.h1
-rw-r--r--src/corelib/thread/qmutex.cpp55
-rw-r--r--src/corelib/thread/qmutex.h57
-rw-r--r--src/corelib/thread/qmutex_p.h2
-rw-r--r--src/corelib/thread/qmutex_win.cpp4
-rw-r--r--src/corelib/thread/qmutexpool_p.h5
-rw-r--r--src/corelib/thread/qorderedmutexlocker_p.h1
-rw-r--r--src/corelib/thread/qreadwritelock_p.h2
-rw-r--r--src/corelib/thread/qthread.cpp4
-rw-r--r--src/corelib/thread/qthread_unix.cpp4
-rw-r--r--src/corelib/thread/qthread_win.cpp44
-rw-r--r--src/corelib/thread/qwaitcondition.h3
-rw-r--r--src/corelib/thread/qwaitcondition.qdoc15
-rw-r--r--src/corelib/thread/qwaitcondition_win.cpp5
16 files changed, 163 insertions, 74 deletions
diff --git a/src/corelib/thread/qfuture.h b/src/corelib/thread/qfuture.h
index 7ae5c68bb9..1f0c747f40 100644
--- a/src/corelib/thread/qfuture.h
+++ b/src/corelib/thread/qfuture.h
@@ -65,13 +65,7 @@ public:
explicit QFuture(QFutureInterface<T> *p) // internal
: d(*p)
{ }
- QFuture(const QFuture &other)
- : d(other.d)
- { }
- ~QFuture()
- { }
- inline QFuture &operator=(const QFuture &other);
bool operator==(const QFuture &other) const { return (d == other.d); }
bool operator!=(const QFuture &other) const { return (d != other.d); }
@@ -157,13 +151,6 @@ public: // Warning: the d pointer is not documented and is considered private.
};
template <typename T>
-inline QFuture<T> &QFuture<T>::operator=(const QFuture<T> &other)
-{
- d = other.d;
- return *this;
-}
-
-template <typename T>
inline T QFuture<T>::result() const
{
d.waitForResult(0);
@@ -195,13 +182,7 @@ public:
explicit QFuture(QFutureInterfaceBase *p) // internal
: d(*p)
{ }
- QFuture(const QFuture &other)
- : d(other.d)
- { }
- ~QFuture()
- { }
- QFuture &operator=(const QFuture &other);
bool operator==(const QFuture &other) const { return (d == other.d); }
bool operator!=(const QFuture &other) const { return (d != other.d); }
@@ -248,12 +229,6 @@ public:
mutable QFutureInterfaceBase d;
};
-inline QFuture<void> &QFuture<void>::operator=(const QFuture<void> &other)
-{
- d = other.d;
- return *this;
-}
-
inline QFuture<void> QFutureInterface<void>::future()
{
return QFuture<void>(this);
diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h
index 1787ff3b93..559d26e231 100644
--- a/src/corelib/thread/qfutureinterface.h
+++ b/src/corelib/thread/qfutureinterface.h
@@ -285,21 +285,13 @@ template <>
class QFutureInterface<void> : public QFutureInterfaceBase
{
public:
- QFutureInterface<void>(State initialState = NoState)
+ explicit QFutureInterface<void>(State initialState = NoState)
: QFutureInterfaceBase(initialState)
{ }
- QFutureInterface<void>(const QFutureInterface<void> &other)
- : QFutureInterfaceBase(other)
- { }
static QFutureInterface<void> canceledResult()
{ return QFutureInterface(State(Started | Finished | Canceled)); }
- QFutureInterface<void> &operator=(const QFutureInterface<void> &other)
- {
- QFutureInterfaceBase::operator=(other);
- return *this;
- }
inline QFuture<void> future(); // implemented in qfuture.h
diff --git a/src/corelib/thread/qfutureinterface_p.h b/src/corelib/thread/qfutureinterface_p.h
index f5f0e7047f..ee8dfe1354 100644
--- a/src/corelib/thread/qfutureinterface_p.h
+++ b/src/corelib/thread/qfutureinterface_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <QtCore/private/qglobal_p.h>
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qcoreevent.h>
#include <QtCore/qlist.h>
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 878a920ffc..366413e82e 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -264,6 +264,61 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
return lockInternal(timeout);
}
+/*! \fn bool QMutex::try_lock()
+ \since 5.8
+
+ This function is provided for compatibility with the Standard Library
+ concept \c Lockable. It is equivalent to tryLock().
+*/
+
+/*! \fn bool QMutex::try_lock_for(std::chrono::duration<Rep, Period> duration)
+ \since 5.8
+
+ Attempts to lock the mutex. This function returns \c true if the lock
+ was obtained; otherwise it returns \c false. If another thread has
+ locked the mutex, this function will wait for at most \a duration
+ for the mutex to become available.
+
+ Note: Passing a negative duration as the \a duration is equivalent to
+ calling try_lock(). This behavior is different from tryLock.
+
+ If the lock was obtained, the mutex must be unlocked with unlock()
+ before another thread can successfully lock it.
+
+ Calling this function multiple times on the same mutex from the
+ same thread is allowed if this mutex is a
+ \l{QMutex::Recursive}{recursive mutex}. If this mutex is a
+ \l{QMutex::NonRecursive}{non-recursive mutex}, this function will
+ \e always return false when attempting to lock the mutex
+ recursively.
+
+ \sa lock(), unlock()
+*/
+
+/*! \fn bool QMutex::try_lock_until(std::chrono::time_point<Clock, Duration> timePoint)
+ \since 5.8
+
+ Attempts to lock the mutex. This function returns \c true if the lock
+ was obtained; otherwise it returns \c false. If another thread has
+ locked the mutex, this function will wait at most until \a timePoint
+ for the mutex to become available.
+
+ Note: Passing a \a timePoint which has already passed is equivalent
+ to calling try_lock. This behavior is different from tryLock.
+
+ If the lock was obtained, the mutex must be unlocked with unlock()
+ before another thread can successfully lock it.
+
+ Calling this function multiple times on the same mutex from the
+ same thread is allowed if this mutex is a
+ \l{QMutex::Recursive}{recursive mutex}. If this mutex is a
+ \l{QMutex::NonRecursive}{non-recursive mutex}, this function will
+ \e always return false when attempting to lock the mutex
+ recursively.
+
+ \sa lock(), unlock()
+*/
+
/*! \fn void QMutex::unlock()
Unlocks the mutex. Attempting to unlock a mutex in a different
thread to the one that locked it results in an error. Unlocking a
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h
index a06bcd99ac..3a0e22e3bd 100644
--- a/src/corelib/thread/qmutex.h
+++ b/src/corelib/thread/qmutex.h
@@ -44,6 +44,10 @@
#include <QtCore/qatomic.h>
#include <new>
+#if QT_HAS_INCLUDE(<chrono>)
+# include <chrono>
+#endif
+
QT_BEGIN_NAMESPACE
@@ -60,11 +64,13 @@ class QMutexData;
class Q_CORE_EXPORT QBasicMutex
{
public:
+ // BasicLockable concept
inline void lock() QT_MUTEX_LOCK_NOEXCEPT {
if (!fastTryLock())
lockInternal();
}
+ // BasicLockable concept
inline void unlock() Q_DECL_NOTHROW {
Q_ASSERT(d_ptr.load()); //mutex must be locked
if (!fastTryUnlock())
@@ -75,6 +81,9 @@ public:
return fastTryLock();
}
+ // Lockable concept
+ bool try_lock() Q_DECL_NOTHROW { return tryLock(); }
+
bool isRecursive() Q_DECL_NOTHROW; //### Qt6: remove me
bool isRecursive() const Q_DECL_NOTHROW;
@@ -112,10 +121,41 @@ public:
explicit QMutex(RecursionMode mode = NonRecursive);
~QMutex();
+ // BasicLockable concept
void lock() QT_MUTEX_LOCK_NOEXCEPT;
bool tryLock(int timeout = 0) QT_MUTEX_LOCK_NOEXCEPT;
+ // BasicLockable concept
void unlock() Q_DECL_NOTHROW;
+ // Lockable concept
+ bool try_lock() QT_MUTEX_LOCK_NOEXCEPT { return tryLock(); }
+
+#if QT_HAS_INCLUDE(<chrono>)
+ // TimedLockable concept
+ template <class Rep, class Period>
+ bool try_lock_for(std::chrono::duration<Rep, Period> duration)
+ {
+ // N4606 § 30.4.1.3 [thread.timedmutex.requirements]/5 specifies that
+ // a duration less than or equal to duration.zero() shall result in a
+ // try_lock, unlike QMutex's tryLock with a negative duration which
+ // results in a lock.
+
+ if (duration <= duration.zero())
+ return tryLock(0);
+ return tryLock(std::chrono::duration_cast<std::chrono::milliseconds>(duration).count());
+ }
+
+ // TimedLockable concept
+ template<class Clock, class Duration>
+ bool try_lock_until(std::chrono::time_point<Clock, Duration> timePoint)
+ {
+ // Implemented in terms of try_lock_for to honor the similar
+ // requirement in N4606 § 30.4.1.3 [thread.timedmutex.requirements]/12.
+
+ return try_lock_for(timePoint - Clock::now());
+ }
+#endif
+
bool isRecursive() const Q_DECL_NOTHROW
{ return QBasicMutex::isRecursive(); }
@@ -189,9 +229,26 @@ public:
inline void lock() Q_DECL_NOTHROW {}
inline bool tryLock(int timeout = 0) Q_DECL_NOTHROW { Q_UNUSED(timeout); return true; }
+ inline bool try_lock() Q_DECL_NOTHROW { return true; }
inline void unlock() Q_DECL_NOTHROW {}
inline bool isRecursive() const Q_DECL_NOTHROW { return true; }
+#if QT_HAS_INCLUDE(<chrono>) || defined(Q_QDOC)
+ template <class Rep, class Period>
+ inline bool try_lock_for(std::chrono::duration<Rep, Period> duration) Q_DECL_NOTHROW
+ {
+ Q_UNUSED(duration);
+ return true;
+ }
+
+ template<class Clock, class Duration>
+ inline bool try_lock_until(std::chrono::time_point<Clock, Duration> timePoint) Q_DECL_NOTHROW
+ {
+ Q_UNUSED(timePoint);
+ return true;
+ }
+#endif
+
private:
Q_DISABLE_COPY(QMutex)
};
diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h
index 20cc5f1f5e..4e6f522a37 100644
--- a/src/corelib/thread/qmutex_p.h
+++ b/src/corelib/thread/qmutex_p.h
@@ -54,7 +54,7 @@
// We mean it.
//
-#include <QtCore/qglobal.h>
+#include <QtCore/private/qglobal_p.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qmutex.h>
#include <QtCore/qatomic.h>
diff --git a/src/corelib/thread/qmutex_win.cpp b/src/corelib/thread/qmutex_win.cpp
index acb0f9dc61..3c314a4c0c 100644
--- a/src/corelib/thread/qmutex_win.cpp
+++ b/src/corelib/thread/qmutex_win.cpp
@@ -61,11 +61,7 @@ QMutexPrivate::~QMutexPrivate()
bool QMutexPrivate::wait(int timeout)
{
-#ifndef Q_OS_WINCE
return (WaitForSingleObjectEx(event, timeout < 0 ? INFINITE : timeout, FALSE) == WAIT_OBJECT_0);
-#else
- return (WaitForSingleObject(event, timeout < 0 ? INFINITE : timeout) == WAIT_OBJECT_0);
-#endif
}
void QMutexPrivate::wakeUp() Q_DECL_NOTHROW
diff --git a/src/corelib/thread/qmutexpool_p.h b/src/corelib/thread/qmutexpool_p.h
index 796e65d960..58d853b0e3 100644
--- a/src/corelib/thread/qmutexpool_p.h
+++ b/src/corelib/thread/qmutexpool_p.h
@@ -44,13 +44,14 @@
// W A R N I N G
// -------------
//
-// This file is not part of the Qt API. It exists for the convenience
-// of QSettings. This header file may change from version to
+// 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/private/qglobal_p.h>
#include "QtCore/qatomic.h"
#include "QtCore/qmutex.h"
#include "QtCore/qvarlengtharray.h"
diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h
index f54f7c705d..81c7c5268c 100644
--- a/src/corelib/thread/qorderedmutexlocker_p.h
+++ b/src/corelib/thread/qorderedmutexlocker_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <QtCore/private/qglobal_p.h>
#include <QtCore/qmutex.h>
#include <functional>
diff --git a/src/corelib/thread/qreadwritelock_p.h b/src/corelib/thread/qreadwritelock_p.h
index 24d25eb2be..bb58dfab56 100644
--- a/src/corelib/thread/qreadwritelock_p.h
+++ b/src/corelib/thread/qreadwritelock_p.h
@@ -52,7 +52,7 @@
// We mean it.
//
-#include <QtCore/qglobal.h>
+#include <QtCore/private/qglobal_p.h>
#include <QtCore/qhash.h>
#include <QtCore/QWaitCondition>
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 4aac24f454..7118ad5c9b 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -403,7 +403,7 @@ QThread::QThread(QThreadPrivate &dd, QObject *parent)
Note that deleting a QThread object will not stop the execution
of the thread it manages. Deleting a running QThread (i.e.
- isFinished() returns \c false) will probably result in a program
+ isFinished() returns \c false) will result in a program
crash. Wait for the finished() signal before deleting the
QThread.
*/
@@ -418,7 +418,7 @@ QThread::~QThread()
locker.relock();
}
if (d->running && !d->finished && !d->data->isAdopted)
- qWarning("QThread: Destroyed while thread is still running");
+ qFatal("QThread: Destroyed while thread is still running");
d->data->thread = 0;
}
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index deedd61c17..ba5f2dca95 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -45,7 +45,7 @@
#include <private/qcoreapplication_p.h>
#include <private/qcore_unix_p.h>
-#if defined(Q_OS_OSX)
+#if defined(Q_OS_DARWIN)
# include <private/qeventdispatcher_cf_p.h>
#else
# if !defined(QT_NO_GLIB)
@@ -279,7 +279,7 @@ typedef void*(*QtThreadCallback)(void*);
void QThreadPrivate::createEventDispatcher(QThreadData *data)
{
-#if defined(Q_OS_OSX)
+#if defined(Q_OS_DARWIN)
bool ok = false;
int value = qEnvironmentVariableIntValue("QT_EVENT_DISPATCHER_CORE_FOUNDATION", &ok);
if (ok && value > 0)
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index ef1799a021..a14c193bad 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -55,15 +55,10 @@
#include <qt_windows.h>
#ifndef Q_OS_WINRT
-#ifndef Q_OS_WINCE
-#ifndef _MT
-#define _MT
-#endif // _MT
-#include <process.h>
-#else // !Q_OS_WINCE
-#include "qfunctions_wince.h"
-#endif // Q_OS_WINCE
-#else // !Q_OS_WINRT
+# ifndef _MT
+# define _MT
+# endif // _MT
+# include <process.h>
#endif // Q_OS_WINRT
#ifndef QT_NO_THREAD
@@ -150,7 +145,6 @@ QThreadData *QThreadData::current(bool createIfNecessary)
// WinRT API?
} else {
HANDLE realHandle = INVALID_HANDLE_VALUE;
-#if !defined(Q_OS_WINCE) || (defined(_WIN32_WCE) && (_WIN32_WCE>=0x600))
DuplicateHandle(GetCurrentProcess(),
GetCurrentThread(),
GetCurrentProcess(),
@@ -158,9 +152,6 @@ QThreadData *QThreadData::current(bool createIfNecessary)
0,
FALSE,
DUPLICATE_SAME_ACCESS);
-#else
- realHandle = reinterpret_cast<HANDLE>(GetCurrentThreadId());
-#endif
qt_watch_adopted_thread(realHandle, threadData->thread);
}
}
@@ -190,9 +181,7 @@ void qt_watch_adopted_thread(const HANDLE adoptedThreadHandle, QThread *qthread)
QMutexLocker lock(&qt_adopted_thread_watcher_mutex);
if (GetCurrentThreadId() == qt_adopted_thread_watcher_id) {
-#if !defined(Q_OS_WINCE) || (defined(_WIN32_WCE) && (_WIN32_WCE>=0x600))
CloseHandle(adoptedThreadHandle);
-#endif
return;
}
@@ -291,9 +280,7 @@ DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID)
data->deref();
QMutexLocker lock(&qt_adopted_thread_watcher_mutex);
-#if !defined(Q_OS_WINCE) || (defined(_WIN32_WCE) && (_WIN32_WCE>=0x600))
CloseHandle(qt_adopted_thread_handles.at(handleIndex));
-#endif
qt_adopted_thread_handles.remove(handleIndex);
qt_adopted_qthreads.remove(qthreadIndex);
}
@@ -306,7 +293,7 @@ DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID)
return 0;
}
-#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
+#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINRT)
#ifndef Q_OS_WIN64
# define ULONG_PTR DWORD
@@ -336,7 +323,7 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName)
{
}
}
-#endif // !QT_NO_DEBUG && Q_CC_MSVC && !Q_OS_WINCE && !Q_OS_WINRT
+#endif // !QT_NO_DEBUG && Q_CC_MSVC && !Q_OS_WINRT
/**************************************************************************
** QThreadPrivate
@@ -378,7 +365,7 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
else
createEventDispatcher(data);
-#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
+#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINRT)
// sets the name of the current thread.
QByteArray objectName = thr->objectName().toLocal8Bit();
qt_set_thread_name((HANDLE)-1,
@@ -453,7 +440,7 @@ int QThread::idealThreadCount() Q_DECL_NOTHROW
void QThread::yieldCurrentThread()
{
-#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
+#if !defined(Q_OS_WINRT)
SwitchToThread();
#else
::Sleep(0);
@@ -495,7 +482,6 @@ void QThread::start(Priority priority)
d->returnCode = 0;
d->interruptionRequested = false;
-#ifndef Q_OS_WINRT
/*
NOTE: we create the thread in the suspended state, set the
priority and then resume the thread.
@@ -506,9 +492,21 @@ void QThread::start(Priority priority)
less than NormalPriority), but the newly created thread preempts
its 'parent' and runs at normal priority.
*/
+#if defined(Q_CC_MSVC) && !defined(_DLL) // && !defined(Q_OS_WINRT)
+# ifdef Q_OS_WINRT
+ // If you wish to accept the memory leaks, uncomment the part above.
+ // See:
+ // https://support.microsoft.com/en-us/kb/104641
+ // https://msdn.microsoft.com/en-us/library/kdzttdcb.aspx
+# error "Microsoft documentation says this combination leaks memory every time a thread is started. " \
+ "Please change your build back to -MD/-MDd or, if you understand this issue and want to continue, " \
+ "edit this source file."
+# endif
+ // MSVC -MT or -MTd build
d->handle = (Qt::HANDLE) _beginthreadex(NULL, d->stackSize, QThreadPrivate::start,
this, CREATE_SUSPENDED, &(d->id));
-#else // !Q_OS_WINRT
+#else
+ // MSVC -MD or -MDd or MinGW build
d->handle = (Qt::HANDLE) CreateThread(NULL, d->stackSize, (LPTHREAD_START_ROUTINE)QThreadPrivate::start,
this, CREATE_SUSPENDED, reinterpret_cast<LPDWORD>(&d->id));
#endif // Q_OS_WINRT
diff --git a/src/corelib/thread/qwaitcondition.h b/src/corelib/thread/qwaitcondition.h
index d2e018834a..a0c6766833 100644
--- a/src/corelib/thread/qwaitcondition.h
+++ b/src/corelib/thread/qwaitcondition.h
@@ -65,6 +65,9 @@ public:
void wakeOne();
void wakeAll();
+ void notify_one() { wakeOne(); }
+ void notify_all() { wakeAll(); }
+
private:
Q_DISABLE_COPY(QWaitCondition)
diff --git a/src/corelib/thread/qwaitcondition.qdoc b/src/corelib/thread/qwaitcondition.qdoc
index d7de323922..eebc28f059 100644
--- a/src/corelib/thread/qwaitcondition.qdoc
+++ b/src/corelib/thread/qwaitcondition.qdoc
@@ -172,3 +172,18 @@
\sa wakeOne(), wakeAll()
*/
+
+
+/*! \fn void QWaitCondition::notify_one()
+ \since 5.8
+
+ This function is provided for STL compatibility. It is equivalent
+ to wakeOne().
+*/
+
+/*! \fn void QWaitCondition::notify_all()
+ \since 5.8
+
+ This function is provided for STL compatibility. It is equivalent
+ to wakeAll().
+*/
diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp
index a95ca0b8fd..e6610f18c8 100644
--- a/src/corelib/thread/qwaitcondition_win.cpp
+++ b/src/corelib/thread/qwaitcondition_win.cpp
@@ -115,12 +115,7 @@ bool QWaitConditionPrivate::wait(QWaitConditionEvent *wce, unsigned long time)
{
// wait for the event
bool ret = false;
-#ifndef Q_OS_WINCE
switch (WaitForSingleObjectEx(wce->event, time, FALSE)) {
-#else
- switch (WaitForSingleObject(wce->event, time)) {
-#endif
-
default: break;
case WAIT_OBJECT_0: