Use qthread_win.cpp for WinRT as well

Since of Windows (Phone) 8.1 most of the desktop's thread functionality
is also available, so we might be able to share the code and get rid of
the extra implementation for WinRT.

Task-number: QTBUG-43837
Change-Id: I0ce907cd94899834527f88c70e1e395bafdb14b3
Reviewed-by: Maurice Kalinowski <maurice.kalinowski@theqtcompany.com>
This commit is contained in:
Oliver Wolff 2015-06-10 12:48:17 +02:00
parent 4ce05c6084
commit bf24838c33
7 changed files with 66 additions and 528 deletions

View File

@ -144,7 +144,10 @@ private:
IID_PPV_ARGS(&application));
RETURN_VOID_IF_FAILED("Failed to get the application factory");
ComPtr<ICoreApplicationView> view;
static ComPtr<ICoreApplicationView> view;
if (view)
return;
hr = application->get_MainView(&view);
RETURN_VOID_IF_FAILED("Failed to get the main view");
@ -166,13 +169,6 @@ QEventDispatcherWinRT::QEventDispatcherWinRT(QObject *parent)
{
Q_D(QEventDispatcherWinRT);
// Special treatment for the WinMain thread, as it is created before the UI
static bool firstThread = true;
if (firstThread) {
firstThread = false;
return;
}
d->fetchCoreDispatcher();
}
@ -212,6 +208,7 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
DWORD waitResult = WaitForMultipleObjectsEx(timerHandles.count(), timerHandles.constData(), FALSE, 1, TRUE);
if (waitResult >= WAIT_OBJECT_0 && waitResult < WAIT_OBJECT_0 + timerHandles.count()) {
const HANDLE handle = timerHandles.value(waitResult - WAIT_OBJECT_0);
ResetEvent(handle);
const int timerId = d->timerHandleToId.value(handle);
if (timerId == INTERRUPT_HANDLE)
break;
@ -288,8 +285,8 @@ void QEventDispatcherWinRT::registerTimer(int timerId, int interval, Qt::TimerTy
TimeSpan period;
period.Duration = interval ? (interval * 10000) : 1; // TimeSpan is based on 100-nanosecond units
IThreadPoolTimer *timer;
const HANDLE handle = CreateEventEx(NULL, NULL, NULL, SYNCHRONIZE|EVENT_MODIFY_STATE);
const HANDLE cancelHandle = CreateEventEx(NULL, NULL, NULL, SYNCHRONIZE|EVENT_MODIFY_STATE);
const HANDLE handle = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, SYNCHRONIZE | EVENT_MODIFY_STATE);
const HANDLE cancelHandle = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, SYNCHRONIZE|EVENT_MODIFY_STATE);
HRESULT hr = d->timerFactory->CreatePeriodicTimerWithCompletion(
Callback<ITimerElapsedHandler>([handle, cancelHandle](IThreadPoolTimer *timer) {
DWORD cancelResult = WaitForSingleObjectEx(cancelHandle, 0, TRUE);
@ -486,7 +483,9 @@ bool QEventDispatcherWinRT::event(QEvent *e)
QEventDispatcherWinRTPrivate::QEventDispatcherWinRTPrivate()
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
const bool isGuiThread = QCoreApplication::instance() &&
QThread::currentThread() == QCoreApplication::instance()->thread();
CoInitializeEx(NULL, isGuiThread ? COINIT_APARTMENTTHREADED : COINIT_MULTITHREADED);
HRESULT hr;
hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Threading_ThreadPoolTimer).Get(), &timerFactory);
Q_ASSERT_SUCCEEDED(hr);

View File

@ -171,19 +171,10 @@ 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;
# else
ABI::Windows::Foundation::IAsyncAction *handle;
# endif
unsigned int id;
int waiters;
bool terminationEnabled, terminatePending;

View File

@ -32,7 +32,7 @@
****************************************************************************/
//#define WINVER 0x0500
#if (_WIN32_WINNT < 0x0400)
#if !defined Q_OS_WINRT && (_WIN32_WINNT < 0x0400)
#define _WIN32_WINNT 0x0400
#endif
@ -46,18 +46,25 @@
#include <qpointer.h>
#include <private/qcoreapplication_p.h>
#ifndef Q_OS_WINRT
#include <private/qeventdispatcher_win_p.h>
#else
#include <private/qeventdispatcher_winrt_p.h>
#endif
#include <qt_windows.h>
#ifndef Q_OS_WINRT
#ifndef Q_OS_WINCE
#ifndef _MT
#define _MT
#endif
#endif // _MT
#include <process.h>
#else
#else // !Q_OS_WINCE
#include "qfunctions_wince.h"
#endif
#endif // Q_OS_WINCE
#else // !Q_OS_WINRT
#endif // Q_OS_WINRT
#ifndef QT_NO_THREAD
QT_BEGIN_NAMESPACE
@ -171,7 +178,11 @@ void qt_watch_adopted_thread(const HANDLE adoptedThreadHandle, QThread *qthread)
// Start watcher thread if it is not already running.
if (qt_adopted_thread_watcher_id == 0) {
if (qt_adopted_thread_wakeup == 0) {
#ifndef Q_OS_WINRT
qt_adopted_thread_wakeup = CreateEvent(0, false, false, 0);
#else
qt_adopted_thread_wakeup = CreateEventEx(0, NULL, 0, EVENT_ALL_ACCESS);
#endif
qt_adopted_thread_handles.prepend(qt_adopted_thread_wakeup);
}
@ -210,13 +221,21 @@ DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID)
// no need to loop, no timeout
offset = 0;
count = handlesCopy.count();
#ifndef Q_OS_WINRT
ret = WaitForMultipleObjects(handlesCopy.count(), handlesCopy.constData(), false, INFINITE);
#else
ret = WaitForMultipleObjectsEx(handlesCopy.count(), handlesCopy.constData(), false, INFINITE, false);
#endif
} else {
int loop = 0;
do {
offset = loop * MAXIMUM_WAIT_OBJECTS;
count = qMin(handlesCopy.count() - offset, MAXIMUM_WAIT_OBJECTS);
#ifndef Q_OS_WINRT
ret = WaitForMultipleObjects(count, handlesCopy.constData() + offset, false, 100);
#else
ret = WaitForMultipleObjectsEx(count, handlesCopy.constData() + offset, false, 100, false);
#endif
loop = (loop + 1) % loops;
} while (ret == WAIT_TIMEOUT);
}
@ -263,7 +282,7 @@ DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID)
return 0;
}
#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE)
#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
#ifndef Q_OS_WIN64
# define ULONG_PTR DWORD
@ -293,7 +312,7 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName)
{
}
}
#endif // !QT_NO_DEBUG && Q_CC_MSVC && !Q_OS_WINCE
#endif // !QT_NO_DEBUG && Q_CC_MSVC && !Q_OS_WINCE && !Q_OS_WINRT
/**************************************************************************
** QThreadPrivate
@ -303,7 +322,11 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName)
void QThreadPrivate::createEventDispatcher(QThreadData *data)
{
#ifndef Q_OS_WINRT
QEventDispatcherWin32 *theEventDispatcher = new QEventDispatcherWin32;
#else
QEventDispatcherWinRT *theEventDispatcher = new QEventDispatcherWinRT;
#endif
data->eventDispatcher.storeRelease(theEventDispatcher);
theEventDispatcher->startingUp();
}
@ -331,7 +354,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)
#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
// sets the name of the current thread.
QByteArray objectName = thr->objectName().toLocal8Bit();
qt_set_thread_name((HANDLE)-1,
@ -396,13 +419,17 @@ 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;
}
void QThread::yieldCurrentThread()
{
#ifndef Q_OS_WINCE
#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
SwitchToThread();
#else
::Sleep(0);
@ -444,6 +471,7 @@ 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.
@ -456,6 +484,10 @@ void QThread::start(Priority priority)
*/
d->handle = (Qt::HANDLE) _beginthreadex(NULL, d->stackSize, QThreadPrivate::start,
this, CREATE_SUSPENDED, &(d->id));
#else // !Q_OS_WINRT
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
if (!d->handle) {
qErrnoWarning(errno, "QThread::start: Failed to create thread");
@ -521,7 +553,10 @@ void QThread::terminate()
return;
}
// Calling ExitThread() in setTerminationEnabled is all we can do on WinRT
#ifndef Q_OS_WINRT
TerminateThread(d->handle, 0);
#endif
QThreadPrivate::finish(this, false);
}
@ -541,7 +576,11 @@ bool QThread::wait(unsigned long time)
locker.mutex()->unlock();
bool ret = false;
#ifndef Q_OS_WINRT
switch (WaitForSingleObject(d->handle, time)) {
#else
switch (WaitForSingleObjectEx(d->handle, time, false)) {
#endif
case WAIT_OBJECT_0:
ret = true;
break;
@ -582,7 +621,11 @@ 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);
#else
ExitThread(0);
#endif
}
}

View File

@ -1,450 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** 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 The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $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(&notifierFactory));
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(), &notifier);
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();
threadData->thread->d_func()->createEventDispatcher(threadData);
winmainThread = false;
}
}
return threadData;
}
void QAdoptedThread::init()
{
Q_D(QThread);
d->handle = Q_NULLPTR;
d->id = 0;
}
/**************************************************************************
** 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

View File

@ -50,11 +50,6 @@ 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

View File

@ -67,7 +67,6 @@ extern "C" {
#include <qvector.h>
#include <qdir.h>
#include <qstandardpaths.h>
#include <qthread.h>
#include <wrl.h>
#include <Windows.ApplicationModel.core.h>
@ -276,9 +275,6 @@ int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
if (FAILED(RoInitialize(RO_INIT_MULTITHREADED)))
return 1;
// Mark the main thread
QThread::currentThread();
Core::ICoreApplication *appFactory;
if (FAILED(RoGetActivationFactory(qHString(CoreApplicationClass), IID_PPV_ARGS(&appFactory))))
return 2;

View File

@ -669,9 +669,7 @@ void NativeThreadWrapper::start(FunctionPointer functionPointer, void *data)
#if defined Q_OS_UNIX
const int state = pthread_create(&nativeThreadHandle, 0, NativeThreadWrapper::runUnix, this);
Q_UNUSED(state);
#elif defined(Q_OS_WINRT)
// creating a new worker from within the GUI thread is not supported
#elif defined(Q_OS_WINCE)
#elif defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
nativeThreadHandle = CreateThread(NULL, 0 , (LPTHREAD_START_ROUTINE)NativeThreadWrapper::runWin , this, 0, NULL);
#elif defined Q_OS_WIN
unsigned thrdid = 0;
@ -690,10 +688,12 @@ void NativeThreadWrapper::join()
{
#if defined Q_OS_UNIX
pthread_join(nativeThreadHandle, 0);
#elif defined Q_OS_WINRT
// not supported
#elif defined Q_OS_WIN
#ifndef Q_OS_WINCE
WaitForSingleObjectEx(nativeThreadHandle, INFINITE, FALSE);
#else
WaitForSingleObject(nativeThreadHandle, INFINITE);
#endif
CloseHandle(nativeThreadHandle);
#endif
}
@ -747,9 +747,6 @@ void testNativeThreadAdoption(void *)
}
void tst_QThread::nativeThreadAdoption()
{
#ifdef Q_OS_WINRT
QSKIP("Native thread adoption is not supported on WinRT.");
#endif
threadAdoptedOk = false;
mainThread = QThread::currentThread();
NativeThreadWrapper nativeThread;
@ -773,9 +770,6 @@ void adoptedThreadAffinityFunction(void *arg)
void tst_QThread::adoptedThreadAffinity()
{
#ifdef Q_OS_WINRT
QSKIP("Native thread adoption is not supported on WinRT.");
#endif
QThread *affinity[2] = { 0, 0 };
NativeThreadWrapper thread;
@ -788,9 +782,6 @@ void tst_QThread::adoptedThreadAffinity()
void tst_QThread::adoptedThreadSetPriority()
{
#ifdef Q_OS_WINRT
QSKIP("Native thread adoption is not supported on WinRT.");
#endif
NativeThreadWrapper nativeThread;
nativeThread.setWaitForStop();
nativeThread.startAndWait();
@ -818,9 +809,6 @@ void tst_QThread::adoptedThreadSetPriority()
void tst_QThread::adoptedThreadExit()
{
#ifdef Q_OS_WINRT
QSKIP("Native thread adoption is not supported on WinRT.");
#endif
NativeThreadWrapper nativeThread;
nativeThread.setWaitForStop();
@ -850,9 +838,6 @@ void adoptedThreadExecFunction(void *)
void tst_QThread::adoptedThreadExec()
{
#ifdef Q_OS_WINRT
QSKIP("Native thread adoption is not supported on WinRT.");
#endif
NativeThreadWrapper nativeThread;
nativeThread.start(adoptedThreadExecFunction);
nativeThread.join();
@ -863,9 +848,6 @@ void tst_QThread::adoptedThreadExec()
*/
void tst_QThread::adoptedThreadFinished()
{
#ifdef Q_OS_WINRT
QSKIP("Native thread adoption is not supported on WinRT.");
#endif
NativeThreadWrapper nativeThread;
nativeThread.setWaitForStop();
nativeThread.startAndWait();
@ -876,17 +858,11 @@ void tst_QThread::adoptedThreadFinished()
nativeThread.join();
QTestEventLoop::instance().enterLoop(5);
#if defined(Q_OS_WINRT)
QEXPECT_FAIL("", "QTBUG-31397: Known not to work on WinRT", Abort);
#endif
QVERIFY(!QTestEventLoop::instance().timeout());
}
void tst_QThread::adoptedThreadExecFinished()
{
#ifdef Q_OS_WINRT
QSKIP("Native thread adoption is not supported on WinRT.");
#endif
NativeThreadWrapper nativeThread;
nativeThread.setWaitForStop();
nativeThread.startAndWait(adoptedThreadExecFunction);
@ -902,9 +878,6 @@ void tst_QThread::adoptedThreadExecFinished()
void tst_QThread::adoptMultipleThreads()
{
#ifdef Q_OS_WINRT
QSKIP("Native thread adoption is not supported on WinRT.");
#endif
#if defined(Q_OS_WIN)
// Windows CE is not capable of handling that many threads. On the emulator it is dead with 26 threads already.
# if defined(Q_OS_WINCE)
@ -936,18 +909,12 @@ void tst_QThread::adoptMultipleThreads()
}
QTestEventLoop::instance().enterLoop(5);
#if defined(Q_OS_WINRT)
QEXPECT_FAIL("", "QTBUG-31397: Known not to work on WinRT", Abort);
#endif
QVERIFY(!QTestEventLoop::instance().timeout());
QCOMPARE(recorder.activationCount.load(), numThreads);
}
void tst_QThread::adoptMultipleThreadsOverlap()
{
#ifdef Q_OS_WINRT
QSKIP("Native thread adoption is not supported on WinRT.");
#endif
#if defined(Q_OS_WIN)
// Windows CE is not capable of handling that many threads. On the emulator it is dead with 26 threads already.
# if defined(Q_OS_WINCE)
@ -984,9 +951,6 @@ void tst_QThread::adoptMultipleThreadsOverlap()
}
QTestEventLoop::instance().enterLoop(5);
#if defined(Q_OS_WINRT)
QEXPECT_FAIL("", "QTBUG-31397: Known not to work on WinRT", Abort);
#endif
QVERIFY(!QTestEventLoop::instance().timeout());
QCOMPARE(recorder.activationCount.load(), numThreads);
}