diff options
author | Andrew Christian <andrew.christian@nokia.com> | 2012-03-21 08:31:02 -0400 |
---|---|---|
committer | Chris Craig <ext-chris.craig@nokia.com> | 2012-03-21 16:04:41 +0100 |
commit | 6490c4501e8a2c4f734bb163d273000f43b21de9 (patch) | |
tree | a1de4fbe28b119698faaf2fa7f8a0552dbcc754b | |
parent | b429341fc681860b5ef582fe0e1101d522d830e9 (diff) |
Updated idle delegate classes and tests
* Added enabled property to delegates to universally turn them on and off
* Changed the default IdleDelegate to CpuIdleDelegate
* Added test case for enabling/disabling idle delegate
Change-Id: I6683aa19821f84afea25e8fd97c284863791e7ed
Reviewed-by: Chris Craig <ext-chris.craig@nokia.com>
-rw-r--r-- | src/core/cpuidledelegate.cpp | 23 | ||||
-rw-r--r-- | src/core/cpuidledelegate.h | 4 | ||||
-rw-r--r-- | src/core/idledelegate.cpp | 57 | ||||
-rw-r--r-- | src/core/idledelegate.h | 15 | ||||
-rw-r--r-- | src/core/processbackendmanager.cpp | 8 | ||||
-rw-r--r-- | src/core/timeoutidledelegate.cpp | 20 | ||||
-rw-r--r-- | src/core/timeoutidledelegate.h | 4 | ||||
-rw-r--r-- | tests/auto/processmanager/tst_processmanager.cpp | 55 |
8 files changed, 145 insertions, 41 deletions
diff --git a/src/core/cpuidledelegate.cpp b/src/core/cpuidledelegate.cpp index 46dfe1a..035da6e 100644 --- a/src/core/cpuidledelegate.cpp +++ b/src/core/cpuidledelegate.cpp @@ -95,23 +95,17 @@ CpuIdleDelegate::CpuIdleDelegate(QObject *parent) } /*! - \fn void CpuIdleDelegate::requestIdleCpu(bool request) - - Turn on or off idle requests based on \a request - You must override this function in a subclass. + Turn on or off idle requests based on \a state. */ -void CpuIdleDelegate::requestIdleCpu(bool request) +void CpuIdleDelegate::handleStateChange(bool state) { - if (request != m_timer.isActive()) { - if (request) { - updateStats(true); - m_timer.start(); - } - else { - m_timer.stop(); - } + if (state) { + updateStats(true); + m_timer.start(); } + else + m_timer.stop(); } /*! @@ -200,10 +194,9 @@ int CpuIdleDelegate::idleInterval() const void CpuIdleDelegate::setIdleInterval(int interval) { if (m_timer.interval() != interval) { - bool active = m_timer.isActive(); m_timer.stop(); m_timer.setInterval(interval); - if (active) + if (enabled() && requested()) m_timer.start(); emit idleIntervalChanged(); } diff --git a/src/core/cpuidledelegate.h b/src/core/cpuidledelegate.h index 63b665d..3bc7c65 100644 --- a/src/core/cpuidledelegate.h +++ b/src/core/cpuidledelegate.h @@ -55,7 +55,6 @@ class Q_ADDON_PROCESSMANAGER_EXPORT CpuIdleDelegate : public IdleDelegate public: explicit CpuIdleDelegate(QObject *parent = 0); - virtual void requestIdleCpu(bool request); int idleInterval() const; void setIdleInterval(int interval); @@ -69,6 +68,9 @@ signals: void loadThresholdChanged(); void loadUpdate(double); +protected: + virtual void handleStateChange(bool state); + private slots: void timeout(); diff --git a/src/core/idledelegate.cpp b/src/core/idledelegate.cpp index a28441a..c65f5c7 100644 --- a/src/core/idledelegate.cpp +++ b/src/core/idledelegate.cpp @@ -50,30 +50,81 @@ QT_BEGIN_NAMESPACE_PROCESSMANAGER The IdleDelegate is turned on and off by the \l{requestIdleCpu()} function. The IdleDelegate should emit the \l{idleCpuAvailable()} signal approximately once per second when it is turned on. + + Subclasses should respect the \l{enabled} property by not generating signals + if the IdleDelegate is not enabled. */ /*! + \property IdleDelegate::enabled + \brief Boolean value of whether or not this IdleDelegate should generate signals. + */ + +/*! Construct a IdleDelegate with an optional \a parent. */ IdleDelegate::IdleDelegate(QObject *parent) : QObject(parent) + , m_enabled(true) + , m_requested(false) +{ +} + +/*! + Set the \a enabled property. + */ + +void IdleDelegate::setEnabled(bool value) { + if (m_enabled != value) { + m_enabled = value; + emit enabledChanged(); + if (m_requested) + handleStateChange(m_requested && m_enabled); + } } /*! \fn void IdleDelegate::requestIdleCpu(bool request) + Turn on or off idle requests based on \a request. +*/ + +void IdleDelegate::requestIdleCpu(bool request) +{ + if (m_requested != request) { + m_requested = request; + if (m_enabled) + handleStateChange(m_requested && m_enabled); + } +} - Turn on or off idle requests based on \a request - You must override this function in a subclass. +/*! + \fn void IdleDelegate::handleStateChange(bool state) + Override this in subclasses to turn on and off your Idle delegate + based on \a state (which is just the logical OR of \l{requested()} and \l{enabled()} */ /*! - \fn void IdleDelegate::idleCpuAvailable() + \fn bool IdleDelegate::enabled() const + Return true if this delegate is enabled +*/ + +/*! + \fn bool IdleDelegate::requested() const + Return true if this delegate has been requested +*/ +/*! + \fn void IdleDelegate::idleCpuAvailable() Signal emitted periodically when idle CPU resources are available. */ +/*! + \fn void IdleDelegate::enabledChanged() + Signal emitted when enabled value is changed +*/ + #include "moc_idledelegate.cpp" QT_END_NAMESPACE_PROCESSMANAGER diff --git a/src/core/idledelegate.h b/src/core/idledelegate.h index d58bf83..cadd915 100644 --- a/src/core/idledelegate.h +++ b/src/core/idledelegate.h @@ -48,15 +48,28 @@ QT_BEGIN_NAMESPACE_PROCESSMANAGER class Q_ADDON_PROCESSMANAGER_EXPORT IdleDelegate : public QObject { Q_OBJECT + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) + public: explicit IdleDelegate(QObject *parent = 0); - virtual void requestIdleCpu(bool request) = 0; + virtual void requestIdleCpu(bool request); + + bool enabled() const { return m_enabled; } + void setEnabled(bool); + + bool requested() const { return m_requested; } signals: void idleCpuAvailable(); + void enabledChanged(); + +protected: + virtual void handleStateChange(bool state) = 0; private: Q_DISABLE_COPY(IdleDelegate); + bool m_enabled; + bool m_requested; }; QT_END_NAMESPACE_PROCESSMANAGER diff --git a/src/core/processbackendmanager.cpp b/src/core/processbackendmanager.cpp index 5b1b414..4a63f1a 100644 --- a/src/core/processbackendmanager.cpp +++ b/src/core/processbackendmanager.cpp @@ -40,7 +40,7 @@ #include "processbackendmanager.h" #include "processbackendfactory.h" #include "processbackend.h" -#include "timeoutidledelegate.h" +#include "cpuidledelegate.h" QT_BEGIN_NAMESPACE_PROCESSMANAGER @@ -78,7 +78,7 @@ QT_BEGIN_NAMESPACE_PROCESSMANAGER you do not assign an IdleDelegate, you may subclass the ProcessBackendManager to override the default idle calculations. - If you do not assign an IdleDelegate, the TimeoutIdleDelegate will be + If you do not assign an IdleDelegate, the CpuIdleDelegate will be used by default. If you prefer to not use delegates, you can subclass ProcessBackendManager @@ -119,7 +119,7 @@ QT_BEGIN_NAMESPACE_PROCESSMANAGER /*! Construct a ProcessBackendManager with an optional \a parent - By default, a TimeoutIdleDelegate is assigned to the idleDelegate. + By default, a CpuIdleDelegate is assigned to the idleDelegate. */ ProcessBackendManager::ProcessBackendManager(QObject *parent) @@ -127,7 +127,7 @@ ProcessBackendManager::ProcessBackendManager(QObject *parent) , m_memoryRestricted(false) , m_idleCpuRequest(false) { - m_idleDelegate = new TimeoutIdleDelegate(this); + m_idleDelegate = new CpuIdleDelegate(this); connect(m_idleDelegate, SIGNAL(idleCpuAvailable()), SLOT(idleCpuAvailable())); } diff --git a/src/core/timeoutidledelegate.cpp b/src/core/timeoutidledelegate.cpp index eeb814e..68305fe 100644 --- a/src/core/timeoutidledelegate.cpp +++ b/src/core/timeoutidledelegate.cpp @@ -71,20 +71,15 @@ TimeoutIdleDelegate::TimeoutIdleDelegate(QObject *parent) } /*! - \fn void TimeoutIdleDelegate::requestIdleCpu(bool request) - - Turn on or off idle requests based on \a request - You must override this function in a subclass. + Turn on or off idle requests based on \a state */ -void TimeoutIdleDelegate::requestIdleCpu(bool request) +void TimeoutIdleDelegate::handleStateChange(bool state) { - if (request != m_timer.isActive()) { - if (request) - m_timer.start(); - else - m_timer.stop(); - } + if (state) + m_timer.start(); + else + m_timer.stop(); } /*! @@ -103,10 +98,9 @@ int TimeoutIdleDelegate::idleInterval() const void TimeoutIdleDelegate::setIdleInterval(int interval) { if (m_timer.interval() != interval) { - bool active = m_timer.isActive(); m_timer.stop(); m_timer.setInterval(interval); - if (active) + if (requested() && enabled()) m_timer.start(); emit idleIntervalChanged(); } diff --git a/src/core/timeoutidledelegate.h b/src/core/timeoutidledelegate.h index 98199a8..73f5f0a 100644 --- a/src/core/timeoutidledelegate.h +++ b/src/core/timeoutidledelegate.h @@ -54,7 +54,6 @@ class Q_ADDON_PROCESSMANAGER_EXPORT TimeoutIdleDelegate : public IdleDelegate public: explicit TimeoutIdleDelegate(QObject *parent = 0); - virtual void requestIdleCpu(bool request); int idleInterval() const; void setIdleInterval(int interval); @@ -62,6 +61,9 @@ public: signals: void idleIntervalChanged(); +protected: + virtual void handleStateChange(bool state); + private: Q_DISABLE_COPY(TimeoutIdleDelegate); QTimer m_timer; diff --git a/tests/auto/processmanager/tst_processmanager.cpp b/tests/auto/processmanager/tst_processmanager.cpp index 3ea570e..f66654c 100644 --- a/tests/auto/processmanager/tst_processmanager.cpp +++ b/tests/auto/processmanager/tst_processmanager.cpp @@ -152,6 +152,17 @@ bool isProcessStopped(Q_PID pid) return false; } +static void waitForTimeout(int timeout=5000) +{ + QTime stopWatch; + stopWatch.start(); + forever { + if (stopWatch.elapsed() >= timeout) + break; + QTestEventLoop::instance().enterLoop(1); + } +} + static void waitForInternalProcess(ProcessBackendManager *manager, int num=1, int timeout=5000) { QTime stopWatch; @@ -696,6 +707,8 @@ static void standardTest( clientFunc func, infoFunc infoFixup=0 ) static void prelaunchTest( clientFunc func, infoFunc infoFixup=0 ) { ProcessBackendManager *manager = new ProcessBackendManager; + manager->setIdleDelegate(new TimeoutIdleDelegate); + ProcessInfo info; info.setValue("program", "testPrelaunch/testPrelaunch"); if (infoFixup) @@ -718,11 +731,13 @@ static void prelaunchRestrictedTest( clientFunc func, infoFunc infoFixup=0 ) { ProcessBackendManager *manager = new ProcessBackendManager; manager->setMemoryRestricted(true); + manager->setIdleDelegate(new TimeoutIdleDelegate); ProcessInfo info; info.setValue("program", "testPrelaunch/testPrelaunch"); if (infoFixup) infoFixup(info); + PrelaunchProcessBackendFactory *factory = new PrelaunchProcessBackendFactory; factory->setProcessInfo(info); manager->addFactory(factory); @@ -954,6 +969,7 @@ private slots: void preforkLauncherOomChangeAfter() { preforkLauncherTest(oomChangeAfterClient); } void prelaunchChildAbort(); + void prelaunchWaitIdleTest(); void frontend(); void subclassFrontend(); @@ -972,6 +988,9 @@ void tst_ProcessManager::initTestCase() void tst_ProcessManager::prelaunchChildAbort() { ProcessBackendManager *manager = new ProcessBackendManager; + TimeoutIdleDelegate *delegate = new TimeoutIdleDelegate; + manager->setIdleDelegate(delegate); + ProcessInfo info; info.setValue("program", "testPrelaunch/testPrelaunch"); PrelaunchProcessBackendFactory *factory = new PrelaunchProcessBackendFactory; @@ -979,12 +998,42 @@ void tst_ProcessManager::prelaunchChildAbort() manager->addFactory(factory); // The factory should not have launched - QVERIFY(manager->internalProcesses().count() == 0); - TimeoutIdleDelegate *delegate = qobject_cast<TimeoutIdleDelegate *>(manager->idleDelegate()); - QVERIFY(delegate); + QCOMPARE(manager->internalProcesses().count(), 0); + waitForInternalProcess(manager, 1, delegate->idleInterval() + 2000); + QCOMPARE(manager->internalProcesses().count(), 1); + Q_PID pid = manager->internalProcesses().at(0); + // Kill the prelaunched process and verify that it is restarted + ::kill(pid, SIGKILL); + waitForInternalProcess(manager, 0); + waitForInternalProcess(manager, 1, delegate->idleInterval() + 2000); + delete manager; +} + +void tst_ProcessManager::prelaunchWaitIdleTest() +{ + ProcessBackendManager *manager = new ProcessBackendManager; + TimeoutIdleDelegate *delegate = new TimeoutIdleDelegate; + delegate->setEnabled(false); + manager->setIdleDelegate(delegate); + + ProcessInfo info; + info.setValue("program", "testPrelaunch/testPrelaunch"); + PrelaunchProcessBackendFactory *factory = new PrelaunchProcessBackendFactory; + factory->setProcessInfo(info); + manager->addFactory(factory); + + // The prelaunch process should not launch, even after a timeout + QCOMPARE(manager->internalProcesses().count(), 0); + waitForTimeout(delegate->idleInterval() + 2000); + QCOMPARE(manager->internalProcesses().count(), 0); + + // Now the prelaunch process should launch + delegate->setEnabled(true); waitForInternalProcess(manager, 1, delegate->idleInterval() + 2000); + QCOMPARE(manager->internalProcesses().count(), 1); Q_PID pid = manager->internalProcesses().at(0); + // Kill the prelaunched process and verify that it is restarted ::kill(pid, SIGKILL); waitForInternalProcess(manager, 0); |