summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qeventdispatcher_symbian.cpp
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2010-04-29 11:35:18 (GMT)
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2010-04-29 11:35:18 (GMT)
commite07a0d8acae7feb4142f0848baf68cee267498fe (patch)
treedb4a6eff755a2cea4e8b7125ea88bd886051e339 /src/corelib/kernel/qeventdispatcher_symbian.cpp
parent2dbb9373af3d5cb0d395d99bad285d195ae9fa5c (diff)
downloadQt-e07a0d8acae7feb4142f0848baf68cee267498fe.zip
Qt-e07a0d8acae7feb4142f0848baf68cee267498fe.tar.gz
Qt-e07a0d8acae7feb4142f0848baf68cee267498fe.tar.bz2
Revert "Event dispatcher slow down using delays rather than thread priority"
This reverts commit 99dbc23113eaf40f4e311eb0f21092e54676bd10. This commit caused UI to freeze on gui applications on older phones such as 5800XM and N95.
Diffstat (limited to 'src/corelib/kernel/qeventdispatcher_symbian.cpp')
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp127
1 files changed, 36 insertions, 91 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp
index fa337ca..8c96057 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian.cpp
+++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp
@@ -43,6 +43,7 @@
#include <private/qthread_p.h>
#include <qcoreapplication.h>
#include <private/qcoreapplication_p.h>
+#include <qdatetime.h>
#include <unistd.h>
#include <errno.h>
@@ -635,74 +636,6 @@ void QSocketActiveObject::deleteLater()
}
}
-#ifdef QT_SYMBIAN_PRIORITY_DROP
-class QIdleDetectorThread
-{
-public:
- QIdleDetectorThread()
- : m_state(STATE_RUN), m_stop(false)
- {
- qt_symbian_throwIfError(m_lock.CreateLocal());
- TInt err = m_idleDetectorThread.Create(KNullDesC(), &idleDetectorThreadFunc, 1024, &User::Allocator(), this);
- if (err != KErrNone)
- m_lock.Close();
- qt_symbian_throwIfError(err);
- m_idleDetectorThread.SetPriority(EPriorityAbsoluteBackgroundNormal);
- m_idleDetectorThread.Resume();
- }
-
- ~QIdleDetectorThread()
- {
- // close down the idle thread because if corelib is loaded temporarily, this would leak threads into the host process
- m_stop = true;
- m_lock.Signal();
- m_idleDetectorThread.SetPriority(EPriorityNormal);
- TRequestStatus s;
- m_idleDetectorThread.Logon(s);
- User::WaitForRequest(s);
- m_idleDetectorThread.Close();
- m_lock.Close();
- }
-
- void kick()
- {
- m_state = STATE_KICKED;
- m_lock.Signal();
- }
-
- bool hasRun()
- {
- return m_state == STATE_RUN;
- }
-
-private:
- static TInt idleDetectorThreadFunc(TAny* self)
- {
- static_cast<QIdleDetectorThread*>(self)->IdleLoop();
- return KErrNone;
- }
-
- void IdleLoop()
- {
- while (!m_stop) {
- m_lock.Wait();
- m_state = STATE_RUN;
- }
- }
-
-private:
- enum IdleStates {STATE_KICKED, STATE_RUN} m_state;
- bool m_stop;
- RThread m_idleDetectorThread;
- RFastLock m_lock;
-};
-
-Q_GLOBAL_STATIC(QIdleDetectorThread, idleDetectorThread);
-
-const int maxBusyTime = 2000; // maximum time we allow idle detector to be blocked before worrying, in milliseconds
-const int baseDelay = 1000; // minimum delay time used when backing off to allow idling, in microseconds
-#endif
-
QEventDispatcherSymbian::QEventDispatcherSymbian(QObject *parent)
: QAbstractEventDispatcher(parent),
m_activeScheduler(0),
@@ -713,15 +646,11 @@ QEventDispatcherSymbian::QEventDispatcherSymbian(QObject *parent)
m_iterationCount(0),
m_noSocketEvents(false)
{
-#ifdef QT_SYMBIAN_PRIORITY_DROP
- m_delay = baseDelay;
- m_avgEventTime = 0;
- idleDetectorThread();
-#endif
}
QEventDispatcherSymbian::~QEventDispatcherSymbian()
{
+ m_processHandle.Close();
}
void QEventDispatcherSymbian::startingUp()
@@ -782,7 +711,23 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla
m_interrupt = false;
#ifdef QT_SYMBIAN_PRIORITY_DROP
- QTime eventTimer;
+ /*
+ * This QTime variable is used to measure the time it takes to finish
+ * the event loop. If we take too long in the loop, other processes
+ * may be starved and killed. After the first event has completed, we
+ * take the current time, and if the remaining events take longer than
+ * a preset time, we temporarily lower the priority to force a context
+ * switch. For applications that do not take unecessarily long in the
+ * event loop, the priority will not be altered.
+ */
+ QTime time;
+ enum {
+ FirstRun,
+ SubsequentRun,
+ TimeStarted
+ } timeState = FirstRun;
+
+ TProcessPriority priority;
#endif
while (1) {
@@ -798,18 +743,10 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla
}
#ifdef QT_SYMBIAN_PRIORITY_DROP
- if (idleDetectorThread()->hasRun()) {
- if (m_delay > baseDelay)
- m_delay -= baseDelay;
- m_lastIdleRequestTimer.start();
- idleDetectorThread()->kick();
- } else if (m_lastIdleRequestTimer.elapsed() > maxBusyTime) {
- User::AfterHighRes(m_delay);
- // allow delay to be up to 1/4 of execution time
- if (!idleDetectorThread()->hasRun() && m_delay*3 < m_avgEventTime)
- m_delay += baseDelay;
+ if (timeState == SubsequentRun) {
+ time.start();
+ timeState = TimeStarted;
}
- eventTimer.start();
#endif
TInt error;
@@ -819,12 +756,6 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla
CActiveScheduler::Current()->Error(error);
}
-#ifdef QT_SYMBIAN_PRIORITY_DROP
- int eventDur = eventTimer.elapsed()*1000;
- // average is calcualted as a 5% decaying exponential average
- m_avgEventTime = (m_avgEventTime * 95 + eventDur * 5) / 100;
-#endif
-
if (!handledSymbianEvent) {
qFatal("QEventDispatcherSymbian::processEvents(): Caught Symbian stray signal");
}
@@ -833,6 +764,20 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla
break;
}
block = false;
+#ifdef QT_SYMBIAN_PRIORITY_DROP
+ if (timeState == TimeStarted && time.elapsed() > 100) {
+ priority = m_processHandle.Priority();
+ m_processHandle.SetPriority(EPriorityBackground);
+ time.start();
+ // Slight chance of race condition in the next lines, but nothing fatal
+ // will happen, just wrong priority.
+ if (m_processHandle.Priority() == EPriorityBackground) {
+ m_processHandle.SetPriority(priority);
+ }
+ }
+ if (timeState == FirstRun)
+ timeState = SubsequentRun;
+#endif
};
emit awake();