summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp79
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian_p.h13
-rw-r--r--src/network/socket/qsymbiansocketengine.cpp28
-rw-r--r--src/network/socket/qsymbiansocketengine_p.h4
4 files changed, 77 insertions, 47 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp
index b074ab4..a95e7d5 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian.cpp
+++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp
@@ -134,7 +134,7 @@ private:
* The QCompleteDeferredAOs class is a special object that runs after all others, which will
* reactivate the objects that were previously not run.
*/
-inline QActiveObject::QActiveObject(TInt priority, QEventDispatcherSymbian *dispatcher)
+QActiveObject::QActiveObject(TInt priority, QEventDispatcherSymbian *dispatcher)
: CActive(priority),
m_dispatcher(dispatcher),
m_hasAlreadyRun(false),
@@ -166,12 +166,25 @@ bool QActiveObject::maybeQueueForLater()
}
}
+bool QActiveObject::maybeDeferSocketEvent()
+{
+ Q_ASSERT(!m_hasRunAgain);
+ Q_ASSERT(m_dispatcher);
+ if (!m_dispatcher->areSocketEventsBlocked()) {
+ return false;
+ }
+ m_hasRunAgain = true;
+ m_dispatcher->addDeferredSocketActiveObject(this);
+ return true;
+}
+
void QActiveObject::reactivateAndComplete()
{
+ TInt error = iStatus.Int();
iStatus = KRequestPending;
SetActive();
TRequestStatus *status = &iStatus;
- QEventDispatcherSymbian::RequestComplete(status, KErrNone);
+ QEventDispatcherSymbian::RequestComplete(status, error);
m_hasRunAgain = false;
m_hasAlreadyRun = false;
@@ -634,10 +647,28 @@ void QSocketActiveObject::DoCancel()
void QSocketActiveObject::RunL()
{
+ if (maybeDeferSocketEvent())
+ return;
if (maybeQueueForLater())
return;
- QT_TRYCATCH_LEAVING(m_dispatcher->socketFired(this));
+ QT_TRYCATCH_LEAVING(run());
+}
+
+void QSocketActiveObject::run()
+{
+ QEvent e(QEvent::SockAct);
+ m_inSocketEvent = true;
+ QCoreApplication::sendEvent(m_notifier, &e);
+ m_inSocketEvent = false;
+
+ if (m_deleteLater) {
+ delete this;
+ } else {
+ iStatus = KRequestPending;
+ SetActive();
+ m_dispatcher->reactivateSocketNotifier(m_notifier);
+ }
}
void QSocketActiveObject::deleteLater()
@@ -912,27 +943,6 @@ void QEventDispatcherSymbian::timerFired(int timerId)
return;
}
-void QEventDispatcherSymbian::socketFired(QSocketActiveObject *socketAO)
-{
- if (m_noSocketEvents) {
- m_deferredSocketEvents.append(socketAO);
- return;
- }
-
- QEvent e(QEvent::SockAct);
- socketAO->m_inSocketEvent = true;
- QCoreApplication::sendEvent(socketAO->m_notifier, &e);
- socketAO->m_inSocketEvent = false;
-
- if (socketAO->m_deleteLater) {
- delete socketAO;
- } else {
- socketAO->iStatus = KRequestPending;
- socketAO->SetActive();
- reactivateSocketNotifier(socketAO->m_notifier);
- }
-}
-
void QEventDispatcherSymbian::wakeUpWasCalled()
{
// The reactivation should happen in RunL, right before the call to this function.
@@ -993,6 +1003,12 @@ inline void QEventDispatcherSymbian::addDeferredActiveObject(QActiveObject *obje
inline void QEventDispatcherSymbian::removeDeferredActiveObject(QActiveObject *object)
{
m_deferredActiveObjects.removeAll(object);
+ m_deferredSocketEvents.removeAll(object);
+}
+
+inline void QEventDispatcherSymbian::addDeferredSocketActiveObject(QActiveObject *object)
+{
+ m_deferredSocketEvents.append(object);
}
void QEventDispatcherSymbian::queueDeferredActiveObjectsCompletion()
@@ -1018,7 +1034,8 @@ bool QEventDispatcherSymbian::sendDeferredSocketEvents()
bool sentAnyEvents = false;
while (!m_deferredSocketEvents.isEmpty()) {
sentAnyEvents = true;
- socketFired(m_deferredSocketEvents.takeFirst());
+ QActiveObject *object = m_deferredSocketEvents.takeFirst();
+ object->reactivateAndComplete();
}
return sentAnyEvents;
@@ -1037,17 +1054,18 @@ bool QEventDispatcherSymbian::hasPendingEvents()
void QEventDispatcherSymbian::registerSocketNotifier ( QSocketNotifier * notifier )
{
- //TODO: just need to be able to do something when event loop has sockets disabled
-/* QSocketActiveObject *socketAO = new QSocketActiveObject(this, notifier);
+ //note - this is only for "open C" file descriptors
+ //for native sockets, an active object in the symbian socket engine handles this
+ QSocketActiveObject *socketAO = new QSocketActiveObject(this, notifier);
Q_CHECK_PTR(socketAO);
m_notifiers.insert(notifier, socketAO);
- selectThread().requestSocketEvents(notifier, &socketAO->iStatus);*/
+ selectThread().requestSocketEvents(notifier, &socketAO->iStatus);
}
void QEventDispatcherSymbian::unregisterSocketNotifier ( QSocketNotifier * notifier )
{
- //TODO: just need to be able to do something when event loop has sockets disabled
- /*
+ //note - this is only for "open C" file descriptors
+ //for native sockets, an active object in the symbian socket engine handles this
if (m_selectThread)
m_selectThread->cancelSocketEvents(notifier);
if (m_notifiers.contains(notifier)) {
@@ -1056,7 +1074,6 @@ void QEventDispatcherSymbian::unregisterSocketNotifier ( QSocketNotifier * notif
sockObj->deleteLater();
m_notifiers.remove(notifier);
}
- */
}
void QEventDispatcherSymbian::reactivateSocketNotifier(QSocketNotifier *notifier)
diff --git a/src/corelib/kernel/qeventdispatcher_symbian_p.h b/src/corelib/kernel/qeventdispatcher_symbian_p.h
index bf28144..e07d475 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian_p.h
+++ b/src/corelib/kernel/qeventdispatcher_symbian_p.h
@@ -77,13 +77,14 @@ QT_BEGIN_NAMESPACE
class QEventDispatcherSymbian;
class QTimerActiveObject;
-class Q_AUTOTEST_EXPORT QActiveObject : public CActive
+class Q_CORE_EXPORT QActiveObject : public CActive
{
public:
QActiveObject(TInt priority, QEventDispatcherSymbian *dispatcher);
~QActiveObject();
bool maybeQueueForLater();
+ bool maybeDeferSocketEvent();
void reactivateAndComplete();
@@ -176,6 +177,7 @@ public:
protected:
void DoCancel();
void RunL();
+ void run();
private:
QSocketNotifier *m_notifier;
@@ -244,7 +246,6 @@ public:
void closingDown();
void timerFired(int timerId);
- void socketFired(QSocketActiveObject *socketAO);
void wakeUpWasCalled();
void reactivateSocketNotifier(QSocketNotifier *notifier);
@@ -256,6 +257,9 @@ public:
inline int iterationCount() const { return m_iterationCount; }
+ void addDeferredSocketActiveObject(QActiveObject *object);
+ inline bool areSocketEventsBlocked() const { return m_noSocketEvents; }
+
static void RequestComplete(TRequestStatus *&status, TInt reason);
static void RequestComplete(RThread &threadHandle, TRequestStatus *&status, TInt reason);
@@ -281,8 +285,9 @@ private:
unsigned char m_iterationCount;
bool m_insideTimerEvent;
bool m_noSocketEvents;
- QList<QSocketActiveObject *> m_deferredSocketEvents;
-
+ //deferred until socket events are enabled
+ QList<QActiveObject *> m_deferredSocketEvents;
+ //deferred until idle
QList<QActiveObject *> m_deferredActiveObjects;
int m_delay;
diff --git a/src/network/socket/qsymbiansocketengine.cpp b/src/network/socket/qsymbiansocketengine.cpp
index 688f724..07b2e5a 100644
--- a/src/network/socket/qsymbiansocketengine.cpp
+++ b/src/network/socket/qsymbiansocketengine.cpp
@@ -63,6 +63,7 @@
#include <QCoreApplication>
#include <qabstracteventdispatcher.h>
+#include <private/qeventdispatcher_symbian_p.h>
#include <qsocketnotifier.h>
#include <qnetworkinterface.h>
@@ -187,7 +188,6 @@ bool QSymbianSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType so
TUint protocol = (socketType == QAbstractSocket::UdpSocket) ? KProtocolInetUdp : KProtocolInetTcp;
//Check if there is a user specified session
- RConnection *connection = 0;
QVariant v(q->property("_q_networksession"));
TInt err;
if (v.isValid()) {
@@ -1437,7 +1437,9 @@ void QSymbianSocketEngine::setReadNotificationEnabled(bool enable)
#endif
d->readNotificationsEnabled = enable;
if (enable && d->threadData->eventDispatcher && !d->asyncSelect)
- d->asyncSelect = q_check_ptr(new QAsyncSelect(0, d->nativeSocket, this));
+ 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();
@@ -1459,7 +1461,9 @@ void QSymbianSocketEngine::setWriteNotificationEnabled(bool enable)
#endif
d->writeNotificationsEnabled = enable;
if (enable && d->threadData->eventDispatcher && !d->asyncSelect)
- d->asyncSelect = q_check_ptr(new QAsyncSelect(0, d->nativeSocket, this));
+ 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();
@@ -1483,7 +1487,9 @@ void QSymbianSocketEngine::setExceptionNotificationEnabled(bool enable)
#endif
d->exceptNotificationsEnabled = enable;
if (enable && d->threadData->eventDispatcher && !d->asyncSelect)
- d->asyncSelect = q_check_ptr(new QAsyncSelect(0, d->nativeSocket, this));
+ d->asyncSelect = q_check_ptr(
+ new QAsyncSelect(static_cast<QEventDispatcherSymbian*>(d->threadData->eventDispatcher),
+ d->nativeSocket, this));
if (d->asyncSelect)
d->asyncSelect->IssueRequest();
}
@@ -1597,15 +1603,17 @@ bool QSymbianSocketEngine::event(QEvent* ev)
qDebug() << "PostThreadChangeEvent" << d->readNotificationsEnabled << d->writeNotificationsEnabled << d->exceptNotificationsEnabled;
#endif
// recreate select in new thread
- d->asyncSelect = q_check_ptr(new QAsyncSelect(0, d->nativeSocket, this));
+ 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);
}
-QAsyncSelect::QAsyncSelect(QAbstractEventDispatcher *dispatcher, RSocket& sock, QSymbianSocketEngine *parent)
- : CActive(CActive::EPriorityStandard),
+QAsyncSelect::QAsyncSelect(QEventDispatcherSymbian *dispatcher, RSocket& sock, QSymbianSocketEngine *parent)
+ : QActiveObject(CActive::EPriorityStandard, dispatcher),
m_inSocketEvent(false),
m_deleteLater(false),
m_socket(sock),
@@ -1652,9 +1660,9 @@ TInt QAsyncSelect::RunError(TInt aError)
void QAsyncSelect::run()
{
- //TODO: block when event loop demands it
- //if (maybeQueueForLater())
- // return;
+ //when event loop disabled socket events, defer until later
+ if (maybeDeferSocketEvent())
+ return;
m_inSocketEvent = true;
m_selectBuf() &= m_selectFlags; //the select ioctl reports everything, so mask to only what we requested
//KSockSelectReadContinuation is for reading datagrams in a mode that doesn't discard when the
diff --git a/src/network/socket/qsymbiansocketengine_p.h b/src/network/socket/qsymbiansocketengine_p.h
index 432e4dc..bbe1269 100644
--- a/src/network/socket/qsymbiansocketengine_p.h
+++ b/src/network/socket/qsymbiansocketengine_p.h
@@ -151,10 +151,10 @@ class QSocketNotifier;
class QReadNotifier;
class QWriteNotifier;
class QExceptionNotifier;
-class QAsyncSelect : public CActive
+class QAsyncSelect : public QActiveObject
{
public:
- QAsyncSelect(QAbstractEventDispatcher *dispatcher, RSocket& sock, QSymbianSocketEngine *parent);
+ QAsyncSelect(QEventDispatcherSymbian *dispatcher, RSocket& sock, QSymbianSocketEngine *parent);
~QAsyncSelect();
void deleteLater();