diff options
Diffstat (limited to 'src')
-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; |