summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2011-04-07 14:10:31 (GMT)
committerShane Kearns <shane.kearns@accenture.com>2011-04-08 15:25:33 (GMT)
commit847df81a5680fe4d71196d0afe5e68e41ae49700 (patch)
tree6568afeb603433649d7e22f023535cb98cf2f887 /src
parenta951fb79139498774d021759d0466b4b2ff50e68 (diff)
downloadQt-847df81a5680fe4d71196d0afe5e68e41ae49700.zip
Qt-847df81a5680fe4d71196d0afe5e68e41ae49700.tar.gz
Qt-847df81a5680fe4d71196d0afe5e68e41ae49700.tar.bz2
Implement support for sockets started before the event loop
If there is no event loop when a socket notification is enabled, then invoke the method via a queued connection so that it is run again when the event loop is started. This covers sockets created and having an asynchronous API called before calling QCoreApplication::exec(). Reviewed-by: Markus Goetz
Diffstat (limited to 'src')
-rw-r--r--src/network/socket/qsymbiansocketengine.cpp69
-rw-r--r--src/network/socket/qsymbiansocketengine_p.h2
2 files changed, 28 insertions, 43 deletions
diff --git a/src/network/socket/qsymbiansocketengine.cpp b/src/network/socket/qsymbiansocketengine.cpp
index 165316d..f1b2982 100644
--- a/src/network/socket/qsymbiansocketengine.cpp
+++ b/src/network/socket/qsymbiansocketengine.cpp
@@ -1433,6 +1433,26 @@ void QSymbianSocketEnginePrivate::setError(TInt symbianError)
hasSetSocketError = true;
}
+void QSymbianSocketEngine::startNotifications()
+{
+ Q_D(QSymbianSocketEngine);
+#ifdef QNATIVESOCKETENGINE_DEBUG
+ qDebug() << "QSymbianSocketEngine::startNotifications" << d->readNotificationsEnabled << d->writeNotificationsEnabled << d->exceptNotificationsEnabled;
+#endif
+ if (!d->asyncSelect && (d->readNotificationsEnabled || d->writeNotificationsEnabled || d->exceptNotificationsEnabled)) {
+ if (d->threadData->eventDispatcher) {
+ d->asyncSelect = q_check_ptr(new QAsyncSelect(
+ static_cast<QEventDispatcherSymbian*> (d->threadData->eventDispatcher), d->nativeSocket,
+ this));
+ } else {
+ // call again when event dispatcher has been created
+ QMetaObject::invokeMethod(this, "startNotifications", Qt::QueuedConnection);
+ }
+ }
+ if (d->asyncSelect)
+ d->asyncSelect->IssueRequest();
+}
+
bool QSymbianSocketEngine::isReadNotificationEnabled() const
{
Q_D(const QSymbianSocketEngine);
@@ -1448,13 +1468,7 @@ void QSymbianSocketEngine::setReadNotificationEnabled(bool enable)
qDebug() << "QSymbianSocketEngine::setReadNotificationEnabled" << enable << "socket" << d->socketDescriptor;
#endif
d->readNotificationsEnabled = enable;
- if (enable && d->threadData->eventDispatcher && !d->asyncSelect)
- d->asyncSelect = q_check_ptr(
- new QAsyncSelect(static_cast<QEventDispatcherSymbian*>(d->threadData->eventDispatcher),
- d->nativeSocket, this));
- // TODO: what do we do if event dispatcher doesn't exist yet?
- if (d->asyncSelect)
- d->asyncSelect->IssueRequest();
+ startNotifications();
}
bool QSymbianSocketEngine::isWriteNotificationEnabled() const
@@ -1472,13 +1486,7 @@ void QSymbianSocketEngine::setWriteNotificationEnabled(bool enable)
qDebug() << "QSymbianSocketEngine::setWriteNotificationEnabled" << enable << "socket" << d->socketDescriptor;
#endif
d->writeNotificationsEnabled = enable;
- if (enable && d->threadData->eventDispatcher && !d->asyncSelect)
- d->asyncSelect = q_check_ptr(
- new QAsyncSelect(static_cast<QEventDispatcherSymbian*>(d->threadData->eventDispatcher),
- d->nativeSocket, this));
- // TODO: what do we do if event dispatcher doesn't exist yet?
- if (d->asyncSelect)
- d->asyncSelect->IssueRequest();
+ startNotifications();
}
bool QSymbianSocketEngine::isExceptionNotificationEnabled() const
@@ -1489,7 +1497,6 @@ bool QSymbianSocketEngine::isExceptionNotificationEnabled() const
return false;
}
-// FIXME do we really need this for symbian?
void QSymbianSocketEngine::setExceptionNotificationEnabled(bool enable)
{
Q_D(QSymbianSocketEngine);
@@ -1498,12 +1505,7 @@ void QSymbianSocketEngine::setExceptionNotificationEnabled(bool enable)
qDebug() << "QSymbianSocketEngine::setExceptionNotificationEnabled" << enable << "socket" << d->socketDescriptor;
#endif
d->exceptNotificationsEnabled = enable;
- if (enable && d->threadData->eventDispatcher && !d->asyncSelect)
- d->asyncSelect = q_check_ptr(
- new QAsyncSelect(static_cast<QEventDispatcherSymbian*>(d->threadData->eventDispatcher),
- d->nativeSocket, this));
- if (d->asyncSelect)
- d->asyncSelect->IssueRequest();
+ startNotifications();
}
bool QSymbianSocketEngine::waitForRead(int msecs, bool *timedOut)
@@ -1588,38 +1590,21 @@ 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);
+ if (ev->type() == QEvent::ThreadChange) {
#ifdef QNATIVESOCKETENGINE_DEBUG
- qDebug() << "QSymbianSocketEngine::event";
-#endif
- switch (ev->type()) {
- case QEvent::ThreadChange:
-#ifdef QNATIVESOCKETENGINE_DEBUG
- qDebug() << "ThreadChange" << d->readNotificationsEnabled << d->writeNotificationsEnabled << d->exceptNotificationsEnabled;
+ qDebug() << "QSymbianSocketEngine::event - ThreadChange" << d->readNotificationsEnabled << d->writeNotificationsEnabled << d->exceptNotificationsEnabled;
#endif
if (d->asyncSelect) {
delete d->asyncSelect;
d->asyncSelect = 0;
- QEvent *postThreadChangeEvent = new QEvent(PostThreadChangeEvent);
- QCoreApplication::postEvent(this, postThreadChangeEvent);
+ // recreate select in new thread (because it is queued, the method is called in the new thread context)
+ QMetaObject::invokeMethod(this, "startNotifications", Qt::QueuedConnection);
}
d->selectTimer.Close();
return true;
- case PostThreadChangeEvent:
-#ifdef QNATIVESOCKETENGINE_DEBUG
- qDebug() << "PostThreadChangeEvent" << d->readNotificationsEnabled << d->writeNotificationsEnabled << d->exceptNotificationsEnabled;
-#endif
- // recreate select in new thread
- d->asyncSelect = q_check_ptr(
- new QAsyncSelect(static_cast<QEventDispatcherSymbian*>(d->threadData->eventDispatcher),
- d->nativeSocket, this));
- d->asyncSelect->IssueRequest();
- return true;
}
return QAbstractSocketEngine::event(ev);
}
diff --git a/src/network/socket/qsymbiansocketengine_p.h b/src/network/socket/qsymbiansocketengine_p.h
index bbe1269..85ab54a 100644
--- a/src/network/socket/qsymbiansocketengine_p.h
+++ b/src/network/socket/qsymbiansocketengine_p.h
@@ -134,7 +134,7 @@ public:
bool event(QEvent* ev);
- static const QEvent::Type PostThreadChangeEvent = (QEvent::Type)(QEvent::User + 1);
+ Q_INVOKABLE void startNotifications();
public Q_SLOTS:
// TODO: Why do we do this? This is private Qt implementation stuff anyway, no need for it