summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Christian <andrew.christian@nokia.com>2012-03-21 08:31:02 -0400
committerChris Craig <ext-chris.craig@nokia.com>2012-03-21 16:04:41 +0100
commit6490c4501e8a2c4f734bb163d273000f43b21de9 (patch)
treea1de4fbe28b119698faaf2fa7f8a0552dbcc754b
parentb429341fc681860b5ef582fe0e1101d522d830e9 (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.cpp23
-rw-r--r--src/core/cpuidledelegate.h4
-rw-r--r--src/core/idledelegate.cpp57
-rw-r--r--src/core/idledelegate.h15
-rw-r--r--src/core/processbackendmanager.cpp8
-rw-r--r--src/core/timeoutidledelegate.cpp20
-rw-r--r--src/core/timeoutidledelegate.h4
-rw-r--r--tests/auto/processmanager/tst_processmanager.cpp55
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);