summaryrefslogtreecommitdiffstats
path: root/src/network
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
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')
-rw-r--r--src/network/socket/qsymbiansocketengine.cpp44
-rw-r--r--src/network/socket/qsymbiansocketengine_p.h4
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;