summaryrefslogtreecommitdiffstats
path: root/src/network/socket/qsymbiansocketengine.cpp
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2011-01-21 15:46:01 (GMT)
committerShane Kearns <shane.kearns@accenture.com>2011-01-21 15:47:59 (GMT)
commitb81b429cb43e19b2211990d0aab80e78e08d87f7 (patch)
tree1f47f5a85b63b83d39a48dc9fe62de3b514c096f /src/network/socket/qsymbiansocketengine.cpp
parentb10fe4c9efa0767c9591fa19c86ff7e5c3f88860 (diff)
downloadQt-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/socket/qsymbiansocketengine.cpp')
-rw-r--r--src/network/socket/qsymbiansocketengine.cpp44
1 files changed, 41 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();
}