QThread: fix race when setting the eventDispatcher
Use QAtomicPointer to make this thread-safe. Change-Id: If71f204699fcefabdb59bd26342d777d1cc9e2a7 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
parent
85b25fc221
commit
f4609b2022
@ -380,7 +380,7 @@ bool QProcessPrivate::createChannel(Channel &channel)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// create the socket notifiers
|
// create the socket notifiers
|
||||||
if (threadData->eventDispatcher) {
|
if (threadData->hasEventDispatcher()) {
|
||||||
if (&channel == &stdinChannel) {
|
if (&channel == &stdinChannel) {
|
||||||
channel.notifier = new QSocketNotifier(channel.pipe[1],
|
channel.notifier = new QSocketNotifier(channel.pipe[1],
|
||||||
QSocketNotifier::Write, q);
|
QSocketNotifier::Write, q);
|
||||||
@ -562,7 +562,7 @@ void QProcessPrivate::startProcess()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (threadData->eventDispatcher) {
|
if (threadData->hasEventDispatcher()) {
|
||||||
startupSocketNotifier = new QSocketNotifier(childStartedPipe[0],
|
startupSocketNotifier = new QSocketNotifier(childStartedPipe[0],
|
||||||
QSocketNotifier::Read, q);
|
QSocketNotifier::Read, q);
|
||||||
QObject::connect(startupSocketNotifier, SIGNAL(activated(int)),
|
QObject::connect(startupSocketNotifier, SIGNAL(activated(int)),
|
||||||
|
@ -528,7 +528,7 @@ void QProcessPrivate::startProcess()
|
|||||||
if (!pid)
|
if (!pid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (threadData->eventDispatcher) {
|
if (threadData->hasEventDispatcher()) {
|
||||||
processFinishedNotifier = new QWinEventNotifier(pid->hProcess, q);
|
processFinishedNotifier = new QWinEventNotifier(pid->hProcess, q);
|
||||||
QObject::connect(processFinishedNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_processDied()));
|
QObject::connect(processFinishedNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_processDied()));
|
||||||
processFinishedNotifier->setEnabled(true);
|
processFinishedNotifier->setEnabled(true);
|
||||||
|
@ -158,7 +158,7 @@ void QProcessPrivate::startProcess()
|
|||||||
if (!pid)
|
if (!pid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (threadData->eventDispatcher) {
|
if (threadData->hasEventDispatcher()) {
|
||||||
processFinishedNotifier = new QWinEventNotifier(pid->hProcess, q);
|
processFinishedNotifier = new QWinEventNotifier(pid->hProcess, q);
|
||||||
QObject::connect(processFinishedNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_processDied()));
|
QObject::connect(processFinishedNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_processDied()));
|
||||||
processFinishedNotifier->setEnabled(true);
|
processFinishedNotifier->setEnabled(true);
|
||||||
|
@ -172,7 +172,7 @@ QAbstractEventDispatcher::~QAbstractEventDispatcher()
|
|||||||
QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
|
QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
|
||||||
{
|
{
|
||||||
QThreadData *data = thread ? QThreadData::get2(thread) : QThreadData::current();
|
QThreadData *data = thread ? QThreadData::get2(thread) : QThreadData::current();
|
||||||
return data->eventDispatcher;
|
return data->eventDispatcher.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -689,7 +689,7 @@ void QCoreApplication::init()
|
|||||||
#ifndef QT_NO_QOBJECT
|
#ifndef QT_NO_QOBJECT
|
||||||
// use the event dispatcher created by the app programmer (if any)
|
// use the event dispatcher created by the app programmer (if any)
|
||||||
if (!QCoreApplicationPrivate::eventDispatcher)
|
if (!QCoreApplicationPrivate::eventDispatcher)
|
||||||
QCoreApplicationPrivate::eventDispatcher = d->threadData->eventDispatcher;
|
QCoreApplicationPrivate::eventDispatcher = d->threadData->eventDispatcher.load();
|
||||||
// otherwise we create one
|
// otherwise we create one
|
||||||
if (!QCoreApplicationPrivate::eventDispatcher)
|
if (!QCoreApplicationPrivate::eventDispatcher)
|
||||||
d->createEventDispatcher();
|
d->createEventDispatcher();
|
||||||
@ -1031,9 +1031,9 @@ bool QCoreApplication::closingDown()
|
|||||||
void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
|
void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
|
||||||
{
|
{
|
||||||
QThreadData *data = QThreadData::current();
|
QThreadData *data = QThreadData::current();
|
||||||
if (!data->eventDispatcher)
|
if (!data->hasEventDispatcher())
|
||||||
return;
|
return;
|
||||||
data->eventDispatcher->processEvents(flags);
|
data->eventDispatcher.load()->processEvents(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1055,11 +1055,11 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
|
|||||||
void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int maxtime)
|
void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int maxtime)
|
||||||
{
|
{
|
||||||
QThreadData *data = QThreadData::current();
|
QThreadData *data = QThreadData::current();
|
||||||
if (!data->eventDispatcher)
|
if (!data->hasEventDispatcher())
|
||||||
return;
|
return;
|
||||||
QElapsedTimer start;
|
QElapsedTimer start;
|
||||||
start.start();
|
start.start();
|
||||||
while (data->eventDispatcher->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
|
while (data->eventDispatcher.load()->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
|
||||||
if (start.elapsed() > maxtime)
|
if (start.elapsed() > maxtime)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1258,8 +1258,9 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
|
|||||||
data->canWait = false;
|
data->canWait = false;
|
||||||
locker.unlock();
|
locker.unlock();
|
||||||
|
|
||||||
if (data->eventDispatcher)
|
QAbstractEventDispatcher* dispatcher = data->eventDispatcher.loadAcquire();
|
||||||
data->eventDispatcher->wakeUp();
|
if (dispatcher)
|
||||||
|
dispatcher->wakeUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1379,8 +1380,8 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type
|
|||||||
}
|
}
|
||||||
|
|
||||||
--data->postEventList.recursion;
|
--data->postEventList.recursion;
|
||||||
if (!data->postEventList.recursion && !data->canWait && data->eventDispatcher)
|
if (!data->postEventList.recursion && !data->canWait && data->hasEventDispatcher())
|
||||||
data->eventDispatcher->wakeUp();
|
data->eventDispatcher.load()->wakeUp();
|
||||||
|
|
||||||
// clear the global list, i.e. remove everything that was
|
// clear the global list, i.e. remove everything that was
|
||||||
// delivered.
|
// delivered.
|
||||||
|
@ -103,7 +103,7 @@ QEventLoop::QEventLoop(QObject *parent)
|
|||||||
Q_D(QEventLoop);
|
Q_D(QEventLoop);
|
||||||
if (!QCoreApplication::instance()) {
|
if (!QCoreApplication::instance()) {
|
||||||
qWarning("QEventLoop: Cannot be used without QApplication");
|
qWarning("QEventLoop: Cannot be used without QApplication");
|
||||||
} else if (!d->threadData->eventDispatcher) {
|
} else if (!d->threadData->eventDispatcher.load()) {
|
||||||
QThreadPrivate::createEventDispatcher(d->threadData);
|
QThreadPrivate::createEventDispatcher(d->threadData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,9 +131,9 @@ QEventLoop::~QEventLoop()
|
|||||||
bool QEventLoop::processEvents(ProcessEventsFlags flags)
|
bool QEventLoop::processEvents(ProcessEventsFlags flags)
|
||||||
{
|
{
|
||||||
Q_D(QEventLoop);
|
Q_D(QEventLoop);
|
||||||
if (!d->threadData->eventDispatcher)
|
if (!d->threadData->eventDispatcher.load())
|
||||||
return false;
|
return false;
|
||||||
return d->threadData->eventDispatcher->processEvents(flags);
|
return d->threadData->eventDispatcher.load()->processEvents(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -234,7 +234,7 @@ int QEventLoop::exec(ProcessEventsFlags flags)
|
|||||||
void QEventLoop::processEvents(ProcessEventsFlags flags, int maxTime)
|
void QEventLoop::processEvents(ProcessEventsFlags flags, int maxTime)
|
||||||
{
|
{
|
||||||
Q_D(QEventLoop);
|
Q_D(QEventLoop);
|
||||||
if (!d->threadData->eventDispatcher)
|
if (!d->threadData->eventDispatcher.load())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QElapsedTimer start;
|
QElapsedTimer start;
|
||||||
@ -263,12 +263,12 @@ void QEventLoop::processEvents(ProcessEventsFlags flags, int maxTime)
|
|||||||
void QEventLoop::exit(int returnCode)
|
void QEventLoop::exit(int returnCode)
|
||||||
{
|
{
|
||||||
Q_D(QEventLoop);
|
Q_D(QEventLoop);
|
||||||
if (!d->threadData->eventDispatcher)
|
if (!d->threadData->eventDispatcher.load())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
d->returnCode = returnCode;
|
d->returnCode = returnCode;
|
||||||
d->exit = true;
|
d->exit = true;
|
||||||
d->threadData->eventDispatcher->interrupt();
|
d->threadData->eventDispatcher.load()->interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -292,9 +292,9 @@ bool QEventLoop::isRunning() const
|
|||||||
void QEventLoop::wakeUp()
|
void QEventLoop::wakeUp()
|
||||||
{
|
{
|
||||||
Q_D(QEventLoop);
|
Q_D(QEventLoop);
|
||||||
if (!d->threadData->eventDispatcher)
|
if (!d->threadData->eventDispatcher.load())
|
||||||
return;
|
return;
|
||||||
d->threadData->eventDispatcher->wakeUp();
|
d->threadData->eventDispatcher.load()->wakeUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -216,8 +216,8 @@ QObjectPrivate::~QObjectPrivate()
|
|||||||
{
|
{
|
||||||
if (extraData && !extraData->runningTimers.isEmpty()) {
|
if (extraData && !extraData->runningTimers.isEmpty()) {
|
||||||
// unregister pending timers
|
// unregister pending timers
|
||||||
if (threadData->eventDispatcher)
|
if (threadData->eventDispatcher.load())
|
||||||
threadData->eventDispatcher->unregisterTimers(q_ptr);
|
threadData->eventDispatcher.load()->unregisterTimers(q_ptr);
|
||||||
|
|
||||||
// release the timer ids back to the pool
|
// release the timer ids back to the pool
|
||||||
for (int i = 0; i < extraData->runningTimers.size(); ++i)
|
for (int i = 0; i < extraData->runningTimers.size(); ++i)
|
||||||
@ -1074,7 +1074,7 @@ bool QObject::event(QEvent *e)
|
|||||||
case QEvent::ThreadChange: {
|
case QEvent::ThreadChange: {
|
||||||
Q_D(QObject);
|
Q_D(QObject);
|
||||||
QThreadData *threadData = d->threadData;
|
QThreadData *threadData = d->threadData;
|
||||||
QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher;
|
QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.load();
|
||||||
if (eventDispatcher) {
|
if (eventDispatcher) {
|
||||||
QList<QAbstractEventDispatcher::TimerInfo> timers = eventDispatcher->registeredTimers(this);
|
QList<QAbstractEventDispatcher::TimerInfo> timers = eventDispatcher->registeredTimers(this);
|
||||||
if (!timers.isEmpty()) {
|
if (!timers.isEmpty()) {
|
||||||
@ -1354,9 +1354,9 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData
|
|||||||
++eventsMoved;
|
++eventsMoved;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (eventsMoved > 0 && targetData->eventDispatcher) {
|
if (eventsMoved > 0 && targetData->eventDispatcher.load()) {
|
||||||
targetData->canWait = false;
|
targetData->canWait = false;
|
||||||
targetData->eventDispatcher->wakeUp();
|
targetData->eventDispatcher.load()->wakeUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
// the current emitting thread shouldn't restore currentSender after calling moveToThread()
|
// the current emitting thread shouldn't restore currentSender after calling moveToThread()
|
||||||
@ -1379,7 +1379,7 @@ void QObjectPrivate::_q_reregisterTimers(void *pointer)
|
|||||||
{
|
{
|
||||||
Q_Q(QObject);
|
Q_Q(QObject);
|
||||||
QList<QAbstractEventDispatcher::TimerInfo> *timerList = reinterpret_cast<QList<QAbstractEventDispatcher::TimerInfo> *>(pointer);
|
QList<QAbstractEventDispatcher::TimerInfo> *timerList = reinterpret_cast<QList<QAbstractEventDispatcher::TimerInfo> *>(pointer);
|
||||||
QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher;
|
QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.load();
|
||||||
for (int i = 0; i < timerList->size(); ++i) {
|
for (int i = 0; i < timerList->size(); ++i) {
|
||||||
const QAbstractEventDispatcher::TimerInfo &ti = timerList->at(i);
|
const QAbstractEventDispatcher::TimerInfo &ti = timerList->at(i);
|
||||||
eventDispatcher->registerTimer(ti.timerId, ti.interval, ti.timerType, q);
|
eventDispatcher->registerTimer(ti.timerId, ti.interval, ti.timerType, q);
|
||||||
@ -1438,11 +1438,11 @@ int QObject::startTimer(int interval, Qt::TimerType timerType)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!d->threadData->eventDispatcher) {
|
if (!d->threadData->eventDispatcher.load()) {
|
||||||
qWarning("QObject::startTimer: QTimer can only be used with threads started with QThread");
|
qWarning("QObject::startTimer: QTimer can only be used with threads started with QThread");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int timerId = d->threadData->eventDispatcher->registerTimer(interval, timerType, this);
|
int timerId = d->threadData->eventDispatcher.load()->registerTimer(interval, timerType, this);
|
||||||
if (!d->extraData)
|
if (!d->extraData)
|
||||||
d->extraData = new QObjectPrivate::ExtraData;
|
d->extraData = new QObjectPrivate::ExtraData;
|
||||||
d->extraData->runningTimers.append(timerId);
|
d->extraData->runningTimers.append(timerId);
|
||||||
@ -1472,8 +1472,8 @@ void QObject::killTimer(int id)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->threadData->eventDispatcher)
|
if (d->threadData->eventDispatcher.load())
|
||||||
d->threadData->eventDispatcher->unregisterTimer(id);
|
d->threadData->eventDispatcher.load()->unregisterTimer(id);
|
||||||
|
|
||||||
d->extraData->runningTimers.remove(at);
|
d->extraData->runningTimers.remove(at);
|
||||||
QAbstractEventDispatcherPrivate::releaseTimerId(id);
|
QAbstractEventDispatcherPrivate::releaseTimerId(id);
|
||||||
|
@ -187,10 +187,10 @@ QSocketNotifier::QSocketNotifier(qintptr socket, Type type, QObject *parent)
|
|||||||
d->sntype = type;
|
d->sntype = type;
|
||||||
d->snenabled = true;
|
d->snenabled = true;
|
||||||
|
|
||||||
if (!d->threadData->eventDispatcher) {
|
if (!d->threadData->eventDispatcher.load()) {
|
||||||
qWarning("QSocketNotifier: Can only be used with threads started with QThread");
|
qWarning("QSocketNotifier: Can only be used with threads started with QThread");
|
||||||
} else {
|
} else {
|
||||||
d->threadData->eventDispatcher->registerSocketNotifier(this);
|
d->threadData->eventDispatcher.load()->registerSocketNotifier(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,12 +273,12 @@ void QSocketNotifier::setEnabled(bool enable)
|
|||||||
return;
|
return;
|
||||||
d->snenabled = enable;
|
d->snenabled = enable;
|
||||||
|
|
||||||
if (!d->threadData->eventDispatcher) // perhaps application/thread is shutting down
|
if (!d->threadData->eventDispatcher.load()) // perhaps application/thread is shutting down
|
||||||
return;
|
return;
|
||||||
if (d->snenabled)
|
if (d->snenabled)
|
||||||
d->threadData->eventDispatcher->registerSocketNotifier(this);
|
d->threadData->eventDispatcher.load()->registerSocketNotifier(this);
|
||||||
else
|
else
|
||||||
d->threadData->eventDispatcher->unregisterSocketNotifier(this);
|
d->threadData->eventDispatcher.load()->unregisterSocketNotifier(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ QWinEventNotifier::QWinEventNotifier(HANDLE hEvent, QObject *parent)
|
|||||||
: QObject(*new QWinEventNotifierPrivate(hEvent, false), parent)
|
: QObject(*new QWinEventNotifierPrivate(hEvent, false), parent)
|
||||||
{
|
{
|
||||||
Q_D(QWinEventNotifier);
|
Q_D(QWinEventNotifier);
|
||||||
QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher;
|
QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher.load();
|
||||||
if (!eventDispatcher) {
|
if (!eventDispatcher) {
|
||||||
qWarning("QWinEventNotifier: Can only be used with threads started with QThread");
|
qWarning("QWinEventNotifier: Can only be used with threads started with QThread");
|
||||||
} else {
|
} else {
|
||||||
@ -208,7 +208,7 @@ void QWinEventNotifier::setEnabled(bool enable)
|
|||||||
return;
|
return;
|
||||||
d->enabled = enable;
|
d->enabled = enable;
|
||||||
|
|
||||||
QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher;
|
QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher.load();
|
||||||
if (!eventDispatcher) // perhaps application is shutting down
|
if (!eventDispatcher) // perhaps application is shutting down
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -752,7 +752,7 @@ QThread::QThread(QThreadPrivate &dd, QObject *parent)
|
|||||||
QAbstractEventDispatcher *QThread::eventDispatcher() const
|
QAbstractEventDispatcher *QThread::eventDispatcher() const
|
||||||
{
|
{
|
||||||
Q_D(const QThread);
|
Q_D(const QThread);
|
||||||
return d->data->eventDispatcher;
|
return d->data->eventDispatcher.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -767,7 +767,7 @@ QAbstractEventDispatcher *QThread::eventDispatcher() const
|
|||||||
void QThread::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
|
void QThread::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
|
||||||
{
|
{
|
||||||
Q_D(QThread);
|
Q_D(QThread);
|
||||||
if (d->data->eventDispatcher != 0) {
|
if (d->data->hasEventDispatcher()) {
|
||||||
qWarning("QThread::setEventDispatcher: An event dispatcher has already been created for this thread");
|
qWarning("QThread::setEventDispatcher: An event dispatcher has already been created for this thread");
|
||||||
} else {
|
} else {
|
||||||
eventDispatcher->moveToThread(this);
|
eventDispatcher->moveToThread(this);
|
||||||
|
@ -230,6 +230,8 @@ public:
|
|||||||
|
|
||||||
void ref();
|
void ref();
|
||||||
void deref();
|
void deref();
|
||||||
|
inline bool hasEventDispatcher() const
|
||||||
|
{ return eventDispatcher.load() != 0; }
|
||||||
|
|
||||||
bool canWaitLocked()
|
bool canWaitLocked()
|
||||||
{
|
{
|
||||||
@ -241,7 +243,7 @@ public:
|
|||||||
Qt::HANDLE threadId;
|
Qt::HANDLE threadId;
|
||||||
bool quitNow;
|
bool quitNow;
|
||||||
int loopLevel;
|
int loopLevel;
|
||||||
QAbstractEventDispatcher *eventDispatcher;
|
QAtomicPointer<QAbstractEventDispatcher> eventDispatcher;
|
||||||
QStack<QEventLoop *> eventLoops;
|
QStack<QEventLoop *> eventLoops;
|
||||||
QPostEventList postEventList;
|
QPostEventList postEventList;
|
||||||
bool canWait;
|
bool canWait;
|
||||||
|
@ -258,19 +258,19 @@ typedef void*(*QtThreadCallback)(void*);
|
|||||||
void QThreadPrivate::createEventDispatcher(QThreadData *data)
|
void QThreadPrivate::createEventDispatcher(QThreadData *data)
|
||||||
{
|
{
|
||||||
#if defined(Q_OS_BLACKBERRY)
|
#if defined(Q_OS_BLACKBERRY)
|
||||||
data->eventDispatcher = new QEventDispatcherBlackberry;
|
data->eventDispatcher.storeRelease(new QEventDispatcherBlackberry);
|
||||||
#else
|
#else
|
||||||
#if !defined(QT_NO_GLIB)
|
#if !defined(QT_NO_GLIB)
|
||||||
if (qEnvironmentVariableIsEmpty("QT_NO_GLIB")
|
if (qEnvironmentVariableIsEmpty("QT_NO_GLIB")
|
||||||
&& qEnvironmentVariableIsEmpty("QT_NO_THREADED_GLIB")
|
&& qEnvironmentVariableIsEmpty("QT_NO_THREADED_GLIB")
|
||||||
&& QEventDispatcherGlib::versionSupported())
|
&& QEventDispatcherGlib::versionSupported())
|
||||||
data->eventDispatcher = new QEventDispatcherGlib;
|
data->eventDispatcher.storeRelease(new QEventDispatcherGlib);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
data->eventDispatcher = new QEventDispatcherUNIX;
|
data->eventDispatcher.storeRelease(new QEventDispatcherUNIX);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
data->eventDispatcher->startingUp();
|
data->eventDispatcher.load()->startingUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_THREAD
|
#ifndef QT_NO_THREAD
|
||||||
@ -314,8 +314,8 @@ void *QThreadPrivate::start(void *arg)
|
|||||||
data->quitNow = thr->d_func()->exited;
|
data->quitNow = thr->d_func()->exited;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->eventDispatcher) // custom event dispatcher set?
|
if (data->eventDispatcher.load()) // custom event dispatcher set?
|
||||||
data->eventDispatcher->startingUp();
|
data->eventDispatcher.load()->startingUp();
|
||||||
else
|
else
|
||||||
createEventDispatcher(data);
|
createEventDispatcher(data);
|
||||||
|
|
||||||
@ -358,7 +358,7 @@ void QThreadPrivate::finish(void *arg)
|
|||||||
QThreadStorageData::finish((void **)data);
|
QThreadStorageData::finish((void **)data);
|
||||||
locker.relock();
|
locker.relock();
|
||||||
|
|
||||||
QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher;
|
QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher.load();
|
||||||
if (eventDispatcher) {
|
if (eventDispatcher) {
|
||||||
d->data->eventDispatcher = 0;
|
d->data->eventDispatcher = 0;
|
||||||
locker.unlock();
|
locker.unlock();
|
||||||
|
@ -306,8 +306,9 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName)
|
|||||||
|
|
||||||
void QThreadPrivate::createEventDispatcher(QThreadData *data)
|
void QThreadPrivate::createEventDispatcher(QThreadData *data)
|
||||||
{
|
{
|
||||||
data->eventDispatcher = new QEventDispatcherWin32;
|
QEventDispatcherWin32 *theEventDispatcher = new QEventDispatcherWin32;
|
||||||
data->eventDispatcher->startingUp();
|
data->eventDispatcher.storeRelease(theEventDispatcher);
|
||||||
|
theEventDispatcher->startingUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_THREAD
|
#ifndef QT_NO_THREAD
|
||||||
@ -328,8 +329,8 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
|
|||||||
data->quitNow = thr->d_func()->exited;
|
data->quitNow = thr->d_func()->exited;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->eventDispatcher) // custom event dispatcher set?
|
if (data->eventDispatcher.load()) // custom event dispatcher set?
|
||||||
data->eventDispatcher->startingUp();
|
data->eventDispatcher.load()->startingUp();
|
||||||
else
|
else
|
||||||
createEventDispatcher(data);
|
createEventDispatcher(data);
|
||||||
|
|
||||||
@ -364,7 +365,7 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway)
|
|||||||
QThreadStorageData::finish(tls_data);
|
QThreadStorageData::finish(tls_data);
|
||||||
locker.relock();
|
locker.relock();
|
||||||
|
|
||||||
QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher;
|
QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher.load();
|
||||||
if (eventDispatcher) {
|
if (eventDispatcher) {
|
||||||
d->data->eventDispatcher = 0;
|
d->data->eventDispatcher = 0;
|
||||||
locker.unlock();
|
locker.unlock();
|
||||||
|
@ -107,7 +107,7 @@ public:
|
|||||||
static QAbstractEventDispatcher *qt_qpa_core_dispatcher()
|
static QAbstractEventDispatcher *qt_qpa_core_dispatcher()
|
||||||
{
|
{
|
||||||
if (QCoreApplication::instance())
|
if (QCoreApplication::instance())
|
||||||
return QCoreApplication::instance()->d_func()->threadData->eventDispatcher;
|
return QCoreApplication::instance()->d_func()->threadData->eventDispatcher.load();
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -643,7 +643,7 @@ bool QAbstractSocketPrivate::initSocketLayer(QAbstractSocket::NetworkLayerProtoc
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (threadData->eventDispatcher)
|
if (threadData->hasEventDispatcher())
|
||||||
socketEngine->setReceiver(this);
|
socketEngine->setReceiver(this);
|
||||||
|
|
||||||
#if defined (QABSTRACTSOCKET_DEBUG)
|
#if defined (QABSTRACTSOCKET_DEBUG)
|
||||||
@ -1134,7 +1134,7 @@ void QAbstractSocketPrivate::_q_connectToNextAddress()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start the connect timer.
|
// Start the connect timer.
|
||||||
if (threadData->eventDispatcher) {
|
if (threadData->hasEventDispatcher()) {
|
||||||
if (!connectTimer) {
|
if (!connectTimer) {
|
||||||
connectTimer = new QTimer(q);
|
connectTimer = new QTimer(q);
|
||||||
QObject::connect(connectTimer, SIGNAL(timeout()),
|
QObject::connect(connectTimer, SIGNAL(timeout()),
|
||||||
@ -1159,7 +1159,7 @@ void QAbstractSocketPrivate::_q_connectToNextAddress()
|
|||||||
void QAbstractSocketPrivate::_q_testConnection()
|
void QAbstractSocketPrivate::_q_testConnection()
|
||||||
{
|
{
|
||||||
if (socketEngine) {
|
if (socketEngine) {
|
||||||
if (threadData->eventDispatcher) {
|
if (threadData->hasEventDispatcher()) {
|
||||||
if (connectTimer)
|
if (connectTimer)
|
||||||
connectTimer->stop();
|
connectTimer->stop();
|
||||||
}
|
}
|
||||||
@ -1180,7 +1180,7 @@ void QAbstractSocketPrivate::_q_testConnection()
|
|||||||
addresses.clear();
|
addresses.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (threadData->eventDispatcher) {
|
if (threadData->hasEventDispatcher()) {
|
||||||
if (connectTimer)
|
if (connectTimer)
|
||||||
connectTimer->stop();
|
connectTimer->stop();
|
||||||
}
|
}
|
||||||
@ -1640,7 +1640,7 @@ void QAbstractSocket::connectToHost(const QString &hostName, quint16 port,
|
|||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (d->threadData->eventDispatcher) {
|
if (d->threadData->hasEventDispatcher()) {
|
||||||
// this internal API for QHostInfo either immediately gives us the desired
|
// this internal API for QHostInfo either immediately gives us the desired
|
||||||
// QHostInfo from cache or later calls the _q_startConnecting slot.
|
// QHostInfo from cache or later calls the _q_startConnecting slot.
|
||||||
bool immediateResultValid = false;
|
bool immediateResultValid = false;
|
||||||
@ -1846,7 +1846,7 @@ bool QAbstractSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->threadData->eventDispatcher)
|
if (d->threadData->hasEventDispatcher())
|
||||||
d->socketEngine->setReceiver(d);
|
d->socketEngine->setReceiver(d);
|
||||||
|
|
||||||
QIODevice::open(openMode);
|
QIODevice::open(openMode);
|
||||||
|
@ -1214,7 +1214,7 @@ void QNativeSocketEngine::setReadNotificationEnabled(bool enable)
|
|||||||
Q_D(QNativeSocketEngine);
|
Q_D(QNativeSocketEngine);
|
||||||
if (d->readNotifier) {
|
if (d->readNotifier) {
|
||||||
d->readNotifier->setEnabled(enable);
|
d->readNotifier->setEnabled(enable);
|
||||||
} else if (enable && d->threadData->eventDispatcher) {
|
} else if (enable && d->threadData->hasEventDispatcher()) {
|
||||||
d->readNotifier = new QReadNotifier(d->socketDescriptor, this);
|
d->readNotifier = new QReadNotifier(d->socketDescriptor, this);
|
||||||
d->readNotifier->setEnabled(true);
|
d->readNotifier->setEnabled(true);
|
||||||
}
|
}
|
||||||
@ -1231,7 +1231,7 @@ void QNativeSocketEngine::setWriteNotificationEnabled(bool enable)
|
|||||||
Q_D(QNativeSocketEngine);
|
Q_D(QNativeSocketEngine);
|
||||||
if (d->writeNotifier) {
|
if (d->writeNotifier) {
|
||||||
d->writeNotifier->setEnabled(enable);
|
d->writeNotifier->setEnabled(enable);
|
||||||
} else if (enable && d->threadData->eventDispatcher) {
|
} else if (enable && d->threadData->hasEventDispatcher()) {
|
||||||
d->writeNotifier = new QWriteNotifier(d->socketDescriptor, this);
|
d->writeNotifier = new QWriteNotifier(d->socketDescriptor, this);
|
||||||
d->writeNotifier->setEnabled(true);
|
d->writeNotifier->setEnabled(true);
|
||||||
}
|
}
|
||||||
@ -1248,7 +1248,7 @@ void QNativeSocketEngine::setExceptionNotificationEnabled(bool enable)
|
|||||||
Q_D(QNativeSocketEngine);
|
Q_D(QNativeSocketEngine);
|
||||||
if (d->exceptNotifier) {
|
if (d->exceptNotifier) {
|
||||||
d->exceptNotifier->setEnabled(enable);
|
d->exceptNotifier->setEnabled(enable);
|
||||||
} else if (enable && d->threadData->eventDispatcher) {
|
} else if (enable && d->threadData->hasEventDispatcher()) {
|
||||||
d->exceptNotifier = new QExceptionNotifier(d->socketDescriptor, this);
|
d->exceptNotifier = new QExceptionNotifier(d->socketDescriptor, this);
|
||||||
d->exceptNotifier->setEnabled(true);
|
d->exceptNotifier->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user