diff options
author | Andrew Knight <andrew.knight@digia.com> | 2014-06-19 10:22:16 +0300 |
---|---|---|
committer | Andrew Knight <andrew.knight@digia.com> | 2014-06-25 16:34:39 +0200 |
commit | b46e48f1b72267d14fc4b9e1969f0fc0a4eb739e (patch) | |
tree | 29e23b5ab5bcd9bafdb62fbc67471eb111b6ceca /src/corelib/thread/qthread_win.cpp | |
parent | 50001dc801a695ecd1e6381ff159c0cf2f3c5b55 (diff) |
winrt: Use native threading
Instead of using std::thread, use the WinRT ThreadPool to manage
threads. This allows for setting the scheduling priority, and provides
a path to enable XAML integration (which requires Qt run on a background
thread).
QThread::terminate() is still unsupported, and only the winmain thread
can be adopted due to the behavior of the thread pool when creating
tasks from the GUI thread. The associated tests are now skipped, and
all other QThread tests pass.
Task-number: QTBUG-31397
Change-Id: Ib512a328412e1dffecdc836bc39de3ccd37afa13
Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Diffstat (limited to 'src/corelib/thread/qthread_win.cpp')
-rw-r--r-- | src/corelib/thread/qthread_win.cpp | 147 |
1 files changed, 3 insertions, 144 deletions
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 |