diff options
author | Shane Kearns <shane.kearns@accenture.com> | 2011-01-21 15:46:01 (GMT) |
---|---|---|
committer | Shane Kearns <shane.kearns@accenture.com> | 2011-01-21 15:47:59 (GMT) |
commit | b81b429cb43e19b2211990d0aab80e78e08d87f7 (patch) | |
tree | 1f47f5a85b63b83d39a48dc9fe62de3b514c096f /src/network | |
parent | b10fe4c9efa0767c9591fa19c86ff7e5c3f88860 (diff) | |
download | Qt-b81b429cb43e19b2211990d0aab80e78e08d87f7.zip Qt-b81b429cb43e19b2211990d0aab80e78e08d87f7.tar.gz Qt-b81b429cb43e19b2211990d0aab80e78e08d87f7.tar.bz2 |
Implement moveToThread in the symbian socket engine
The active object used for socket notifications (QAsyncSelect) is
thread specific, so it needs to be deleted and recreated in the new thread.
Reviewed-by: Markus Goetz
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/socket/qsymbiansocketengine.cpp | 44 | ||||
-rw-r--r-- | src/network/socket/qsymbiansocketengine_p.h | 4 |
2 files changed, 45 insertions, 3 deletions
diff --git a/src/network/socket/qsymbiansocketengine.cpp b/src/network/socket/qsymbiansocketengine.cpp index cc55f2a..487f45c 100644 --- a/src/network/socket/qsymbiansocketengine.cpp +++ b/src/network/socket/qsymbiansocketengine.cpp @@ -59,6 +59,8 @@ # include "qtcpserver.h" #endif +#include <QCoreApplication> + #include <qabstracteventdispatcher.h> #include <qsocketnotifier.h> #include <qnetworkinterface.h> @@ -1576,6 +1578,41 @@ qint64 QSymbianSocketEngine::bytesToWrite() const return 0; } +//TODO: is defining PostThreadChangeEvent as QEvent::User + 1 safe? +//TODO: would QMetaObject::invokeMethod(obj, "postThreadChangeSlot", Qt::QueuedConnection) be better? +//TODO: if QTBUG-16787 is implemented, use that instead +bool QSymbianSocketEngine::event(QEvent* ev) +{ + Q_D(QSymbianSocketEngine); + switch (ev->type()) { + case QEvent::ThreadChange: + if (d->asyncSelect) { + delete d->asyncSelect; + d->asyncSelect = 0; + QEvent *postThreadChangeEvent = new QEvent(PostThreadChangeEvent); + QCoreApplication::postEvent(this, postThreadChangeEvent); + } + return true; + case PostThreadChangeEvent: + // recreate select in new thread + d->asyncSelect = q_check_ptr(new QAsyncSelect(0, d->nativeSocket, this)); + if (d->readNotifier) { + d->asyncSelect->setReadNotifier(static_cast<QReadNotifier*>(d->readNotifier)); + setReadNotificationEnabled(d->readNotifier->isEnabled()); + } + if (d->writeNotifier) { + d->asyncSelect->setWriteNotifier(static_cast<QWriteNotifier*>(d->writeNotifier)); + setReadNotificationEnabled(d->writeNotifier->isEnabled()); + } + if (d->exceptNotifier) { + d->asyncSelect->setExceptionNotifier(static_cast<QExceptionNotifier*>(d->exceptNotifier)); + setReadNotificationEnabled(d->exceptNotifier->isEnabled()); + } + return true; + } + return QAbstractSocketEngine::event(ev); +} + QAsyncSelect::QAsyncSelect(QAbstractEventDispatcher *dispatcher, RSocket& sock, QSymbianSocketEngine *parent) : CActive(CActive::EPriorityStandard), m_inSocketEvent(false), @@ -1631,11 +1668,11 @@ void QAsyncSelect::run() m_inSocketEvent = true; m_selectBuf() &= m_selectFlags; //the select ioctl reports everything, so mask to only what we requested //TODO: KSockSelectReadContinuation does what? - if (iReadN && (m_selectBuf() & KSockSelectRead)) { + if (iReadN && ((m_selectBuf() & KSockSelectRead) || iStatus != KErrNone)) { QEvent e(QEvent::SockAct); iReadN->event(&e); } - if (iWriteN && (m_selectBuf() & KSockSelectWrite)) { + if (iWriteN && ((m_selectBuf() & KSockSelectWrite) || iStatus != KErrNone)) { QEvent e(QEvent::SockAct); iWriteN->event(&e); } @@ -1681,7 +1718,8 @@ void QAsyncSelect::IssueRequest() m_selectFlags = selectFlags; } if (m_selectFlags && !IsActive()) { - m_selectBuf() = m_selectFlags; + //always request errors (write notification does not complete on connect errors) + m_selectBuf() = m_selectFlags | KSockSelectExcept; m_socket.Ioctl(KIOctlSelect, iStatus, &m_selectBuf, KSOLSocket); SetActive(); } diff --git a/src/network/socket/qsymbiansocketengine_p.h b/src/network/socket/qsymbiansocketengine_p.h index f36b7dd..8a0b8df 100644 --- a/src/network/socket/qsymbiansocketengine_p.h +++ b/src/network/socket/qsymbiansocketengine_p.h @@ -135,6 +135,10 @@ public: bool isExceptionNotificationEnabled() const; void setExceptionNotificationEnabled(bool enable); + bool event(QEvent* ev); + + static const QEvent::Type PostThreadChangeEvent = (QEvent::Type)(QEvent::User + 1); + public Q_SLOTS: // TODO: Why do we do this? This is private Qt implementation stuff anyway, no need for it // non-virtual override; |