diff options
Diffstat (limited to 'src/corelib/thread')
-rw-r--r-- | src/corelib/thread/qthread_p.h | 23 | ||||
-rw-r--r-- | src/corelib/thread/qthread_win.cpp | 147 | ||||
-rw-r--r-- | src/corelib/thread/qthread_winrt.cpp | 458 | ||||
-rw-r--r-- | src/corelib/thread/thread.pri | 5 |
4 files changed, 479 insertions, 154 deletions
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index e2951b125f..aec553113b 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -65,11 +65,6 @@ #include <algorithm> - -#ifdef Q_OS_WINRT -#include <thread> -#endif - QT_BEGIN_NAMESPACE class QAbstractEventDispatcher; @@ -138,6 +133,10 @@ private: #ifndef QT_NO_THREAD +#ifdef Q_OS_WINRT +namespace ABI { namespace Windows { namespace Foundation { struct IAsyncAction; } } } +#endif + class QThreadPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QThread) @@ -174,19 +173,23 @@ public: #endif // Q_OS_UNIX #ifdef Q_OS_WIN +# ifndef Q_OS_WINRT static unsigned int __stdcall start(void *); static void finish(void *, bool lockAnyway=true); +# else + HRESULT start(ABI::Windows::Foundation::IAsyncAction *); + void finish(bool lockAnyway = true); +# endif # ifndef Q_OS_WINRT Qt::HANDLE handle; - unsigned int id; # else - std::thread *handle; - std::thread::id id; + ABI::Windows::Foundation::IAsyncAction *handle; # endif + unsigned int id; int waiters; bool terminationEnabled, terminatePending; -# endif +#endif // Q_OS_WIN QThreadData *data; static void createEventDispatcher(QThreadData *data); diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index bdc3463b9f..e950a02162 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -40,7 +40,7 @@ ****************************************************************************/ //#define WINVER 0x0500 -#if (_WIN32_WINNT < 0x0400) && !defined(Q_OS_WINRT) +#if (_WIN32_WINNT < 0x0400) #define _WIN32_WINNT 0x0400 #endif @@ -54,19 +54,10 @@ #include <qpointer.h> #include <private/qcoreapplication_p.h> -#ifdef Q_OS_WINRT -#include <private/qeventdispatcher_winrt_p.h> -#else #include <private/qeventdispatcher_win_p.h> -#endif #include <qt_windows.h> -#ifdef Q_OS_WINRT -#include <qelapsedtimer.h> -#include <thread> -#endif - #ifndef Q_OS_WINCE #ifndef _MT #define _MT @@ -79,7 +70,6 @@ #ifndef QT_NO_THREAD QT_BEGIN_NAMESPACE -#ifndef Q_OS_WINRT void qt_watch_adopted_thread(const HANDLE adoptedThreadHandle, QThread *qthread); DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID); @@ -101,38 +91,6 @@ static void qt_free_tls() } } Q_DESTRUCTOR_FUNCTION(qt_free_tls) -#else // !Q_OS_WINRT - -__declspec(thread) static QThreadData* qt_current_thread_data_tls_index = 0; -void qt_create_tls() -{ -} - -static void qt_free_tls() -{ - if (qt_current_thread_data_tls_index) { - qt_current_thread_data_tls_index->deref(); - qt_current_thread_data_tls_index = 0; - } -} - -QThreadData* TlsGetValue(QThreadData*& tls) -{ - Q_ASSERT(tls == qt_current_thread_data_tls_index); - return tls; -} - -void TlsSetValue(QThreadData*& tls, QThreadData* data) -{ - Q_ASSERT(tls == qt_current_thread_data_tls_index); - if (tls) - tls->deref(); - tls = data; - if (tls) - tls->ref(); -} -Q_DESTRUCTOR_FUNCTION(qt_free_tls) -#endif // Q_OS_WINRT /* QThreadData @@ -165,7 +123,6 @@ QThreadData *QThreadData::current(bool createIfNecessary) if (!QCoreApplicationPrivate::theMainThread) { QCoreApplicationPrivate::theMainThread = threadData->thread; -#ifndef Q_OS_WINRT // TODO: is there a way to reflect the branch's behavior using // WinRT API? } else { @@ -182,7 +139,6 @@ QThreadData *QThreadData::current(bool createIfNecessary) realHandle = reinterpret_cast<HANDLE>(GetCurrentThreadId()); #endif qt_watch_adopted_thread(realHandle, threadData->thread); -#endif // !Q_OS_WINRT } } return threadData; @@ -190,16 +146,10 @@ QThreadData *QThreadData::current(bool createIfNecessary) void QAdoptedThread::init() { -#ifndef Q_OS_WINRT d_func()->handle = GetCurrentThread(); d_func()->id = GetCurrentThreadId(); -#else - d_func()->handle = nullptr; - d_func()->id = std::this_thread::get_id(); -#endif } -#ifndef Q_OS_WINRT static QVector<HANDLE> qt_adopted_thread_handles; static QVector<QThread *> qt_adopted_qthreads; static QMutex qt_adopted_thread_watcher_mutex; @@ -352,7 +302,6 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName) } } #endif // !QT_NO_DEBUG && Q_CC_MSVC && !Q_OS_WINCE -#endif // !Q_OS_WINRT /************************************************************************** ** QThreadPrivate @@ -362,11 +311,7 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName) void QThreadPrivate::createEventDispatcher(QThreadData *data) { -#ifdef Q_OS_WINRT - QEventDispatcherWinRT *theEventDispatcher = new QEventDispatcherWinRT; -#else QEventDispatcherWin32 *theEventDispatcher = new QEventDispatcherWin32; -#endif data->eventDispatcher.storeRelease(theEventDispatcher); theEventDispatcher->startingUp(); } @@ -394,7 +339,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_WINCE) // sets the name of the current thread. QByteArray objectName = thr->objectName().toLocal8Bit(); qt_set_thread_name((HANDLE)-1, @@ -440,21 +385,11 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway) d->interruptionRequested = false; if (!d->waiters) { -#ifndef Q_OS_WINRT CloseHandle(d->handle); -#else - d->handle->detach(); - delete d->handle; -#endif d->handle = 0; } -#ifndef Q_OS_WINRT d->id = 0; -#else - d->id = std::thread::id(); -#endif - } /************************************************************************** @@ -469,15 +404,10 @@ Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW int QThread::idealThreadCount() Q_DECL_NOTHROW { SYSTEM_INFO sysinfo; -#ifndef Q_OS_WINRT GetSystemInfo(&sysinfo); -#else - GetNativeSystemInfo(&sysinfo); -#endif return sysinfo.dwNumberOfProcessors; } -#ifndef Q_OS_WINRT void QThread::yieldCurrentThread() { #ifndef Q_OS_WINCE @@ -501,28 +431,6 @@ void QThread::usleep(unsigned long usecs) { ::Sleep((usecs / 1000) + 1); } -#else // !Q_OS_WINRT - -void QThread::yieldCurrentThread() -{ - msleep(1); -} - -void QThread::sleep(unsigned long secs) -{ - msleep(secs * 1000); -} - -void QThread::msleep(unsigned long msecs) -{ - WaitForSingleObjectEx(GetCurrentThread(), msecs, FALSE); -} - -void QThread::usleep(unsigned long usecs) -{ - msleep((usecs / 1000) + 1); -} -#endif // Q_OS_WINRT void QThread::start(Priority priority) { @@ -544,7 +452,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. @@ -609,23 +516,6 @@ void QThread::start(Priority priority) if (ResumeThread(d->handle) == (DWORD) -1) { qErrnoWarning("QThread::start: Failed to resume new thread"); } -#else // !Q_OS_WINRT - d->handle = new std::thread(QThreadPrivate::start, this); - - if (!d->handle) { - qErrnoWarning(errno, "QThread::start: Failed to create thread"); - d->running = false; - d->finished = true; - return; - } - - d->id = d->handle->get_id(); - - if (priority != NormalPriority || priority != InheritPriority) { - qWarning("QThread::start: Failed to set thread priority (not implemented)"); - d->priority = NormalPriority; - } -#endif // Q_OS_WINRT } void QThread::terminate() @@ -639,11 +529,7 @@ void QThread::terminate() return; } -#ifndef Q_OS_WINRT TerminateThread(d->handle, 0); -#else // !Q_OS_WINRT - qWarning("QThread::terminate: Terminate is not supported on WinRT"); -#endif // Q_OS_WINRT QThreadPrivate::finish(this, false); } @@ -652,11 +538,7 @@ bool QThread::wait(unsigned long time) Q_D(QThread); QMutexLocker locker(&d->mutex); -#ifndef Q_OS_WINRT if (d->id == GetCurrentThreadId()) { -#else - if (d->id == std::this_thread::get_id()) { -#endif qWarning("QThread::wait: Thread tried to wait on itself"); return false; } @@ -667,7 +549,6 @@ bool QThread::wait(unsigned long time) locker.mutex()->unlock(); bool ret = false; -#ifndef Q_OS_WINRT switch (WaitForSingleObject(d->handle, time)) { case WAIT_OBJECT_0: ret = true; @@ -680,14 +561,6 @@ bool QThread::wait(unsigned long time) default: break; } -#else // !Q_OS_WINRT - if (!d->finished) { - QElapsedTimer timer; - timer.start(); - while (timer.elapsed() < time && !d->finished) - yieldCurrentThread(); - } -#endif // Q_OS_WINRT locker.mutex()->lock(); --d->waiters; @@ -699,12 +572,7 @@ bool QThread::wait(unsigned long time) } if (d->finished && !d->waiters) { -#ifndef Q_OS_WINRT CloseHandle(d->handle); -#else - d->handle->detach(); - delete d->handle; -#endif d->handle = 0; } @@ -722,16 +590,13 @@ void QThread::setTerminationEnabled(bool enabled) if (enabled && d->terminatePending) { QThreadPrivate::finish(thr, false); locker.unlock(); // don't leave the mutex locked! -#ifndef Q_OS_WINRT _endthreadex(0); -#endif } } // Caller must hold the mutex void QThreadPrivate::setPriority(QThread::Priority threadPriority) { -#ifndef Q_OS_WINRT // copied from start() with a few modifications: int prio; @@ -774,12 +639,6 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority) if (!SetThreadPriority(handle, prio)) { qErrnoWarning("QThread::setPriority: Failed to set thread priority"); } -#else // !Q_OS_WINRT - if (priority != threadPriority) { - qWarning("QThread::setPriority: Failed to set thread priority (not implemented)"); - return; - } -#endif // Q_OS_WINRT } QT_END_NAMESPACE diff --git a/src/corelib/thread/qthread_winrt.cpp b/src/corelib/thread/qthread_winrt.cpp new file mode 100644 index 0000000000..215f04f744 --- /dev/null +++ b/src/corelib/thread/qthread_winrt.cpp @@ -0,0 +1,458 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qthread.h" +#include "qthread_p.h" +#include "qthreadstorage.h" + +#include <QtCore/QElapsedTimer> +#include <QtCore/QUuid> +#include <QtCore/qt_windows.h> +#include <QtCore/qfunctions_winrt.h> +#include <QtCore/private/qcoreapplication_p.h> +#include <QtCore/private/qeventdispatcher_winrt_p.h> + +#include <wrl.h> +#include <windows.system.threading.h> +#include <windows.system.threading.core.h> +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; +using namespace ABI::Windows::Foundation; +using namespace ABI::Windows::System::Threading; +using namespace ABI::Windows::System::Threading::Core; + +#ifndef QT_NO_THREAD +QT_BEGIN_NAMESPACE + +static WorkItemPriority nativePriority(QThread::Priority priority) +{ + switch (priority) { + default: + case QThread::NormalPriority: + return WorkItemPriority_Normal; + case QThread::IdlePriority: + case QThread::LowestPriority: + case QThread::LowPriority: + return WorkItemPriority_Low; + case QThread::HighPriority: + case QThread::HighestPriority: + case QThread::TimeCriticalPriority: + return WorkItemPriority_High; + } +} + +class QWinRTThreadGlobal +{ +public: + QWinRTThreadGlobal() + { + HRESULT hr; + + hr = RoGetActivationFactory( + HString::MakeReference(RuntimeClass_Windows_System_Threading_Core_PreallocatedWorkItem).Get(), + IID_PPV_ARGS(&workItemFactory)); + Q_ASSERT_SUCCEEDED(hr); + + hr = RoGetActivationFactory( + HString::MakeReference(RuntimeClass_Windows_System_Threading_Core_SignalNotifier).Get(), + IID_PPV_ARGS(¬ifierFactory)); + Q_ASSERT_SUCCEEDED(hr); + + QString eventName = QUuid::createUuid().toString(); + dispatchEvent = CreateEventEx(NULL, reinterpret_cast<LPCWSTR>(eventName.utf16()), 0, EVENT_ALL_ACCESS); + + hr = notifierFactory->AttachToEvent( + HStringReference(reinterpret_cast<LPCWSTR>(eventName.utf16())).Get(), + Callback<ISignalHandler>(this, &QWinRTThreadGlobal::dispatch).Get(), ¬ifier); + Q_ASSERT_SUCCEEDED(hr); + hr = notifier->Enable(); + Q_ASSERT_SUCCEEDED(hr); + } + + ~QWinRTThreadGlobal() + { + CloseHandle(dispatchEvent); + } + + void dispatch() + { + SetEvent(dispatchEvent); + } + + void push(QThreadPrivate *d) + { + threads.append(d); + } + +private: + HRESULT dispatch(ISignalNotifier *notifier, boolean timedOut) + { + Q_UNUSED(timedOut); + notifier->Enable(); + if (threads.isEmpty()) + return S_OK; + + QThreadPrivate *thread = threads.takeFirst(); + ComPtr<IPreallocatedWorkItem> workItem; + HRESULT hr = workItemFactory->CreateWorkItemWithPriority( + Callback<IWorkItemHandler>(thread, &QThreadPrivate::start).Get(), + nativePriority(thread->priority), &workItem); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to create thread work item"); + thread->finish(); + return hr; + } + + hr = workItem->RunAsync(&thread->handle); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to run work item"); + thread->finish(); + return hr; + } + + return S_OK; + } + + HANDLE dispatchEvent; + ComPtr<ISignalNotifier> notifier; + ComPtr<ISignalNotifierStatics> notifierFactory; + ComPtr<IPreallocatedWorkItemFactory> workItemFactory; + + QList<QThreadPrivate *> threads; +}; +Q_GLOBAL_STATIC(QWinRTThreadGlobal, g) + +/************************************************************************** + ** QThreadData + *************************************************************************/ + +__declspec(thread) static QThreadData *qt_current_thread_data = 0; + +void QThreadData::clearCurrentThreadData() +{ + qt_current_thread_data = 0; +} + +QThreadData *QThreadData::current(bool createIfNecessary) +{ + static bool winmainThread = true; + QThreadData *threadData = qt_current_thread_data; + if (!threadData && createIfNecessary) { + threadData = new QThreadData; + // This needs to be called prior to new AdoptedThread() to + // avoid recursion. + qt_current_thread_data = threadData; + QT_TRY { + threadData->thread = new QAdoptedThread(threadData); + } QT_CATCH(...) { + qt_current_thread_data = 0; + threadData->deref(); + threadData = 0; + QT_RETHROW; + } + threadData->deref(); + threadData->isAdopted = true; + threadData->threadId = reinterpret_cast<Qt::HANDLE>(GetCurrentThreadId()); + + if (!QCoreApplicationPrivate::theMainThread && !winmainThread) + QCoreApplicationPrivate::theMainThread = threadData->thread; + + if (winmainThread) { + g->dispatch(); + winmainThread = false; + } + } + + return threadData; +} + +void QAdoptedThread::init() +{ + Q_D(QThread); + + d->handle = Q_NULLPTR; + d->id = 0; + d->createEventDispatcher(d->data); +} + +/************************************************************************** + ** QThreadPrivate + *************************************************************************/ + +#endif // QT_NO_THREAD + +void QThreadPrivate::createEventDispatcher(QThreadData *data) +{ + QEventDispatcherWinRT *eventDispatcher = new QEventDispatcherWinRT; + data->eventDispatcher.storeRelease(eventDispatcher); + eventDispatcher->startingUp(); +} + +#ifndef QT_NO_THREAD + +HRESULT QThreadPrivate::start(IAsyncAction *) +{ + Q_Q(QThread); + + qt_current_thread_data = data; + id = GetCurrentThreadId(); + data->threadId = reinterpret_cast<Qt::HANDLE>(id); + QThread::setTerminationEnabled(false); + + { + QMutexLocker locker(&mutex); + data->quitNow = exited; + } + + if (data->eventDispatcher.load()) + data->eventDispatcher.load()->startingUp(); + else + createEventDispatcher(data); + + running = true; + emit q->started(QThread::QPrivateSignal()); + + QThread::setTerminationEnabled(true); + + q->run(); + + finish(); + + return S_OK; +} + +void QThreadPrivate::finish(bool lockAnyway) +{ + Q_Q(QThread); + + QMutexLocker locker(lockAnyway ? &mutex : 0); + isInFinish = true; + priority = QThread::InheritPriority; + void **tls_data = reinterpret_cast<void **>(&data->tls); + locker.unlock(); + emit q->finished(QThread::QPrivateSignal()); + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QThreadStorageData::finish(tls_data); + locker.relock(); + + QAbstractEventDispatcher *eventDispatcher = data->eventDispatcher.load(); + if (eventDispatcher) { + data->eventDispatcher = 0; + locker.unlock(); + eventDispatcher->closingDown(); + delete eventDispatcher; + locker.relock(); + } + + running = false; + finished = true; + isInFinish = false; + interruptionRequested = false; + + if (!waiters) { + if (handle) + handle->Release(); + handle = Q_NULLPTR; + } + + id = 0; +} + +/************************************************************************** + ** QThread + *************************************************************************/ + +Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW +{ + return reinterpret_cast<Qt::HANDLE>(GetCurrentThreadId()); +} + +int QThread::idealThreadCount() Q_DECL_NOTHROW +{ + SYSTEM_INFO sysinfo; + GetNativeSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +} + +void QThread::yieldCurrentThread() +{ + msleep(1); +} + +void QThread::sleep(unsigned long secs) +{ + msleep(secs * 1000); +} + +void QThread::msleep(unsigned long msecs) +{ + WaitForSingleObjectEx(GetCurrentThread(), msecs, FALSE); +} + +void QThread::usleep(unsigned long usecs) +{ + msleep((usecs / 1000) + 1); +} + +void QThread::start(Priority priority) +{ + Q_D(QThread); + QMutexLocker locker(&d->mutex); + + if (d->isInFinish) { + locker.unlock(); + wait(); + locker.relock(); + } + + if (d->running) + return; + + d->finished = false; + d->exited = false; + d->returnCode = 0; + d->interruptionRequested = false; + d->priority = priority == QThread::InheritPriority ? currentThread()->priority() : priority; + g->push(d); + g->dispatch(); + + locker.unlock(); + while (!d->running && !d->finished) { + QAbstractEventDispatcher *eventDispatcher = QThread::currentThread()->eventDispatcher(); + if (eventDispatcher) + eventDispatcher->processEvents(QEventLoop::AllEvents); + else + yieldCurrentThread(); + } +} + +void QThread::terminate() +{ + Q_D(QThread); + QMutexLocker locker(&d->mutex); + if (!d->running) + return; + if (!d->terminationEnabled) { + d->terminatePending = true; + return; + } + + if (d->handle) { + ComPtr<IAsyncInfo> info; + HRESULT hr = d->handle->QueryInterface(IID_PPV_ARGS(&info)); + Q_ASSERT_SUCCEEDED(hr); + hr = info->Cancel(); + if (FAILED(hr)) + qErrnoWarning(hr, "Failed to cancel thread action"); + } + + d->finish(false); +} + +bool QThread::wait(unsigned long time) +{ + Q_D(QThread); + QMutexLocker locker(&d->mutex); + + if (d->id == GetCurrentThreadId()) { + qWarning("QThread::wait: Thread tried to wait on itself"); + return false; + } + if (d->finished || !d->running) + return true; + + ++d->waiters; + locker.mutex()->unlock(); + + // Alternatively, we could check the handle + bool ret = false; + if (!d->finished) { + QElapsedTimer timer; + timer.start(); + while (timer.elapsed() < time && !d->finished) + yieldCurrentThread(); + + ret = d->finished; + } + + locker.mutex()->lock(); + --d->waiters; + + if (ret && !d->finished) { + // thread was terminated by someone else + + d->finish(false); + } + + if (d->finished && !d->waiters) { + if (d->handle) + d->handle->Release(); + d->handle = Q_NULLPTR; + } + + return ret; +} + +void QThread::setTerminationEnabled(bool enabled) +{ + QThread *thr = currentThread(); + Q_ASSERT_X(thr != 0, "QThread::setTerminationEnabled()", + "Current thread was not started with QThread."); + QThreadPrivate *d = thr->d_func(); + QMutexLocker locker(&d->mutex); + d->terminationEnabled = enabled; + if (enabled && d->terminatePending) { + d->finish(false); + locker.unlock(); // don't leave the mutex locked! + } +} + +// Caller must hold the mutex +void QThreadPrivate::setPriority(QThread::Priority threadPriority) +{ + if (running) + qWarning("WinRT threads can't change priority while running."); + + priority = threadPriority; +} + +QT_END_NAMESPACE +#endif // QT_NO_THREAD diff --git a/src/corelib/thread/thread.pri b/src/corelib/thread/thread.pri index 3c1ddd984a..2e027c8e21 100644 --- a/src/corelib/thread/thread.pri +++ b/src/corelib/thread/thread.pri @@ -50,6 +50,11 @@ win32:SOURCES += thread/qmutex_win.cpp \ thread/qthread_win.cpp \ thread/qwaitcondition_win.cpp +winrt { + SOURCES -= thread/qthread_win.cpp + SOURCES += thread/qthread_winrt.cpp +} + integrity:SOURCES += thread/qmutex_unix.cpp \ thread/qthread_unix.cpp \ thread/qwaitcondition_unix.cpp |