summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Christian <andrew.christian@nokia.com>2012-03-19 14:58:30 -0400
committerAndrew Christian <andrew.christian@nokia.com>2012-03-21 11:50:43 +0100
commitb429341fc681860b5ef582fe0e1101d522d830e9 (patch)
tree9c09a23e9dd75c0f94de1328085e44b2aa22ca63
parent60f77b663fe83ce796bdd68813e506585c161fd7 (diff)
Added idle CPU resource allocation for prelaunching
* ProcessBackendFactories indicate a need for extra cycles by setting idleCpuRequest property. * PrelaunchBackendFactory requests this whenever it wants to prelaunch a backend. * ProcessBackendManager aggregates idleCpuRequest properties and passes combined request to IdleDelegate. * IdleDelegate periodically sends idleCpuAvailable() signal to first available factory with outstanding request. * The default IdleDelegate is set to TimeoutIdleDelegate which distributes idleCpuAvailable() signals at regular intervals. This is close to the old prelaunch logic, but now centralized and replaceable. * The CpuIdleDelegate measures system load (Linux & Mac) and distributes idleCpuAvailable() signals when the system load falls below a set level Change-Id: I1ce273b2797ae0f0477dd80ae7bc2c8e3496901e Reviewed-by: Andrew Christian <andrew.christian@nokia.com>
-rw-r--r--src/core/core-lib.pri6
-rw-r--r--src/core/cpuidledelegate.cpp258
-rw-r--r--src/core/cpuidledelegate.h87
-rw-r--r--src/core/idledelegate.cpp79
-rw-r--r--src/core/idledelegate.h64
-rw-r--r--src/core/prelaunchprocessbackendfactory.cpp72
-rw-r--r--src/core/prelaunchprocessbackendfactory.h11
-rw-r--r--src/core/processbackendfactory.cpp57
-rw-r--r--src/core/processbackendfactory.h8
-rw-r--r--src/core/processbackendmanager.cpp149
-rw-r--r--src/core/processbackendmanager.h20
-rw-r--r--src/core/timeoutidledelegate.cpp123
-rw-r--r--src/core/timeoutidledelegate.h72
-rw-r--r--tests/auto/processmanager/tst_processmanager.cpp7
-rw-r--r--tests/manual/cpuload/.gitignore1
-rw-r--r--tests/manual/cpuload/cpuload.pro7
-rw-r--r--tests/manual/cpuload/tst_cpuload.cpp96
17 files changed, 1040 insertions, 77 deletions
diff --git a/src/core/core-lib.pri b/src/core/core-lib.pri
index 42e7f69..358192d 100644
--- a/src/core/core-lib.pri
+++ b/src/core/core-lib.pri
@@ -12,6 +12,9 @@ PUBLIC_HEADERS += \
$$PWD/matchdelegate.h \
$$PWD/rewritedelegate.h \
$$PWD/gdbrewritedelegate.h \
+ $$PWD/idledelegate.h \
+ $$PWD/timeoutidledelegate.h \
+ $$PWD/cpuidledelegate.h \
$$PWD/infomatchdelegate.h \
$$PWD/keymatchdelegate.h \
$$PWD/processinfo.h \
@@ -48,6 +51,9 @@ SOURCES += \
$$PWD/matchdelegate.cpp \
$$PWD/rewritedelegate.cpp \
$$PWD/gdbrewritedelegate.cpp \
+ $$PWD/idledelegate.cpp \
+ $$PWD/timeoutidledelegate.cpp \
+ $$PWD/cpuidledelegate.cpp \
$$PWD/infomatchdelegate.cpp \
$$PWD/keymatchdelegate.cpp \
$$PWD/processinfo.cpp \
diff --git a/src/core/cpuidledelegate.cpp b/src/core/cpuidledelegate.cpp
new file mode 100644
index 0000000..46dfe1a
--- /dev/null
+++ b/src/core/cpuidledelegate.cpp
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QFile>
+
+#ifdef Q_OS_MAC
+#include <mach/mach.h>
+#include <mach/mach_host.h>
+#include <mach/processor_info.h>
+#endif
+
+#include "cpuidledelegate.h"
+
+QT_BEGIN_NAMESPACE_PROCESSMANAGER
+
+const int kIdleTimerInterval = 1000;
+const double kDefaultLoadThreshold = 0.4;
+
+/*!
+ \class CpuIdleDelegate
+ \brief The CpuIdleDelegate class generates a periodic cpu.
+
+ The CpuIdleDelegate class generates a periodic cpu for
+ creation of idle resources. When idle CPU resources are requested
+ it checks the system load level approximately once per second. When
+ the load level is below the threshold set by \l{loadThreshold}, the
+ idleCpuAvailable() signal will be omitted.
+*/
+
+/*!
+ \property CpuIdleDelegate::idleInterval
+ \brief Time in milliseconds before a new idle CPU request will be fulfilled
+ */
+
+/*!
+ \property CpuIdleDelegate::loadThreshold
+ \brief Load level we need to be under to generate idle CPU requests.
+
+ This value is a double that ranges from 0.0 to 1.0. A value greater
+ than or equal to 1.0 guarantees that \l{idleCpuAvailable()} signals
+ will always be emitted. A value less than 0.0 blocks all \l{idleCpuAvailable()}
+ signals.
+ */
+
+
+/*!
+ Construct a CpuIdleDelegate with an optional \a parent.
+*/
+
+CpuIdleDelegate::CpuIdleDelegate(QObject *parent)
+ : IdleDelegate(parent)
+ , m_load(1.0)
+ , m_loadThreshold(kDefaultLoadThreshold)
+ , m_total(0)
+ , m_idle(0)
+{
+ connect(&m_timer, SIGNAL(timeout()), SLOT(timeout()));
+ m_timer.setInterval(kIdleTimerInterval);
+}
+
+/*!
+ \fn void CpuIdleDelegate::requestIdleCpu(bool request)
+
+ Turn on or off idle requests based on \a request
+ You must override this function in a subclass.
+*/
+
+void CpuIdleDelegate::requestIdleCpu(bool request)
+{
+ if (request != m_timer.isActive()) {
+ if (request) {
+ updateStats(true);
+ m_timer.start();
+ }
+ else {
+ m_timer.stop();
+ }
+ }
+}
+
+/*!
+ \internal
+ */
+
+double CpuIdleDelegate::updateStats(bool reset)
+{
+ int idle = 0;
+ int total = 0;
+
+ m_load = 1.0; // Always reset to max in case of error
+
+#if defined(Q_OS_LINUX)
+ QList<QByteArray> stats;
+ QFile file(QStringLiteral("/proc/stat"));
+ if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ QByteArray line = file.readLine();
+ int offset = 0;
+ while (offset < line.size() && !isdigit(line.at(offset)))
+ offset++;
+ if (offset < line.size())
+ stats = line.mid(offset).split(' ');
+ }
+ if (stats.size() < 5)
+ qFatal("Unable to read /proc/stat file");
+
+ idle = stats.at(3).toInt();
+ for (int i = 1 ; i < stats.size() ; i++)
+ total += stats.at(i).toInt();
+
+#elif defined(Q_OS_MAC)
+ natural_t n_cpus;
+ processor_info_t pinfo;
+ mach_msg_type_number_t msg_count;
+ kern_return_t status = host_processor_info(mach_host_self(),
+ PROCESSOR_CPU_LOAD_INFO,
+ &n_cpus,
+ (processor_info_array_t *)&pinfo,
+ &msg_count);
+ if (status != KERN_SUCCESS)
+ qFatal("Unable to read host processor info");
+
+ for (unsigned int cpu = 0 ; cpu < n_cpus ; cpu++) {
+ processor_info_t p = pinfo + (CPU_STATE_MAX * cpu);
+ total += p[CPU_STATE_USER] + p[CPU_STATE_SYSTEM]
+ + p[CPU_STATE_NICE] + p[CPU_STATE_IDLE];
+ idle += p[CPU_STATE_IDLE];
+ }
+ vm_deallocate(mach_task_self(),
+ (vm_address_t)pinfo,
+ (vm_size_t)sizeof(*pinfo) * msg_count);
+#endif
+ if (!reset && total > m_total)
+ m_load = 1.0 - ((float) (idle - m_idle)) / (total - m_total);
+
+ m_total = total;
+ m_idle = idle;
+ return m_load;
+}
+
+/*!
+ \internal
+ */
+
+void CpuIdleDelegate::timeout()
+{
+ if (updateStats(false) <= m_loadThreshold)
+ emit idleCpuAvailable();
+ emit loadUpdate(m_load);
+}
+
+/*!
+ Return the current launch interval in milliseconds
+ */
+
+int CpuIdleDelegate::idleInterval() const
+{
+ return m_timer.interval();
+}
+
+/*!
+ Set the current idle interval to \a interval milliseconds
+*/
+
+void CpuIdleDelegate::setIdleInterval(int interval)
+{
+ if (m_timer.interval() != interval) {
+ bool active = m_timer.isActive();
+ m_timer.stop();
+ m_timer.setInterval(interval);
+ if (active)
+ m_timer.start();
+ emit idleIntervalChanged();
+ }
+}
+
+/*!
+ Return the current load threshold as a number from 0.0 to 1.0
+ */
+
+double CpuIdleDelegate::loadThreshold() const
+{
+ return m_loadThreshold;
+}
+
+/*!
+ Set the current load threshold to \a threshold milliseconds
+*/
+
+void CpuIdleDelegate::setLoadThreshold(double threshold)
+{
+ if (m_loadThreshold != threshold) {
+ m_loadThreshold = threshold;
+ emit loadThresholdChanged();
+ }
+}
+
+/*!
+ \fn void CpuIdleDelegate::idleCpuAvailable()
+ Signal emitted periodically when idle CPU resources are available.
+*/
+
+/*!
+ \fn void CpuIdleDelegate::idleIntervalChanged()
+ This signal is emitted when the idleInterval is changed.
+ */
+
+/*!
+ \fn void CpuIdleDelegate::loadThresholdChanged()
+ This signal is emitted when the loadThreshold is changed.
+ */
+
+/*!
+ \fn void CpuIdleDelegate::loadUpdate(double load)
+ This signal is emitted when the load is read. It mainly
+ serves as a debugging signal. The \a load value will
+ range between 0.0 and 1.0
+ */
+
+
+#include "moc_cpuidledelegate.cpp"
+
+QT_END_NAMESPACE_PROCESSMANAGER
diff --git a/src/core/cpuidledelegate.h b/src/core/cpuidledelegate.h
new file mode 100644
index 0000000..63b665d
--- /dev/null
+++ b/src/core/cpuidledelegate.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CPU_IDLE_DELEGATE_H
+#define CPU_IDLE_DELEGATE_H
+
+#include <QTimer>
+#include "idledelegate.h"
+
+QT_BEGIN_NAMESPACE_PROCESSMANAGER
+
+class ProcessInfo;
+
+class Q_ADDON_PROCESSMANAGER_EXPORT CpuIdleDelegate : public IdleDelegate
+{
+ Q_OBJECT
+ Q_PROPERTY(int idleInterval READ idleInterval WRITE setIdleInterval NOTIFY idleIntervalChanged)
+ Q_PROPERTY(int loadThreshold READ loadThreshold WRITE setLoadThreshold NOTIFY loadThresholdChanged)
+
+public:
+ explicit CpuIdleDelegate(QObject *parent = 0);
+ virtual void requestIdleCpu(bool request);
+
+ int idleInterval() const;
+ void setIdleInterval(int interval);
+
+ double loadThreshold() const;
+ void setLoadThreshold(double threshold);
+
+signals:
+ void idleCpuAvailable();
+ void idleIntervalChanged();
+ void loadThresholdChanged();
+ void loadUpdate(double);
+
+private slots:
+ void timeout();
+
+private:
+ double updateStats(bool);
+
+private:
+ Q_DISABLE_COPY(CpuIdleDelegate);
+ QTimer m_timer;
+ double m_load, m_loadThreshold;
+ int m_total, m_idle;
+};
+
+QT_END_NAMESPACE_PROCESSMANAGER
+
+#endif // CPU_IDLE_DELEGATE_H
diff --git a/src/core/idledelegate.cpp b/src/core/idledelegate.cpp
new file mode 100644
index 0000000..a28441a
--- /dev/null
+++ b/src/core/idledelegate.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "idledelegate.h"
+
+QT_BEGIN_NAMESPACE_PROCESSMANAGER
+
+/*!
+ \class IdleDelegate
+ \brief The IdleDelegate class is a virtual class for gathering idle CPU cycles
+
+ You must subclass this class to do anything useful.
+
+ 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.
+*/
+
+/*!
+ Construct a IdleDelegate with an optional \a parent.
+*/
+
+IdleDelegate::IdleDelegate(QObject *parent)
+ : QObject(parent)
+{
+}
+
+/*!
+ \fn void IdleDelegate::requestIdleCpu(bool request)
+
+ Turn on or off idle requests based on \a request
+ You must override this function in a subclass.
+*/
+
+/*!
+ \fn void IdleDelegate::idleCpuAvailable()
+
+ Signal emitted periodically when idle CPU resources are available.
+*/
+
+#include "moc_idledelegate.cpp"
+
+QT_END_NAMESPACE_PROCESSMANAGER
diff --git a/src/core/idledelegate.h b/src/core/idledelegate.h
new file mode 100644
index 0000000..d58bf83
--- /dev/null
+++ b/src/core/idledelegate.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef IDLE_DELEGATE_H
+#define IDLE_DELEGATE_H
+
+#include <QObject>
+#include "processmanager-global.h"
+
+QT_BEGIN_NAMESPACE_PROCESSMANAGER
+
+class Q_ADDON_PROCESSMANAGER_EXPORT IdleDelegate : public QObject
+{
+ Q_OBJECT
+public:
+ explicit IdleDelegate(QObject *parent = 0);
+ virtual void requestIdleCpu(bool request) = 0;
+
+signals:
+ void idleCpuAvailable();
+
+private:
+ Q_DISABLE_COPY(IdleDelegate);
+};
+
+QT_END_NAMESPACE_PROCESSMANAGER
+
+#endif // IDLE_DELEGATE_H
diff --git a/src/core/prelaunchprocessbackendfactory.cpp b/src/core/prelaunchprocessbackendfactory.cpp
index 97df879..eb64464 100644
--- a/src/core/prelaunchprocessbackendfactory.cpp
+++ b/src/core/prelaunchprocessbackendfactory.cpp
@@ -45,8 +45,6 @@
QT_BEGIN_NAMESPACE_PROCESSMANAGER
-const int kPrelaunchTimerInterval = 1000;
-
/*!
\class PrelaunchProcessBackendFactory
\brief The PrelaunchProcessBackendFactory class creates PrelaunchProcessBackend objects
@@ -56,11 +54,6 @@ const int kPrelaunchTimerInterval = 1000;
*/
/*!
- \property PrelaunchProcessBackendFactory::launchInterval
- \brief Time in milliseconds before a new prelaunch backend will be started
- */
-
-/*!
\property PrelaunchProcessBackendFactory::processInfo
\brief ProcessInfo record used to create the prelaunched process
*/
@@ -85,9 +78,6 @@ PrelaunchProcessBackendFactory::PrelaunchProcessBackendFactory(QObject *parent)
, m_info(NULL)
, m_prelaunchEnabled(true)
{
- connect(&m_timer, SIGNAL(timeout()), SLOT(timeout()));
- m_timer.setSingleShot(true);
- m_timer.setInterval(kPrelaunchTimerInterval);
}
/*!
@@ -162,31 +152,6 @@ ProcessInfo *PrelaunchProcessBackendFactory::processInfo() const
}
/*!
- Return the current launch interval in milliseconds
- */
-
-int PrelaunchProcessBackendFactory::launchInterval() const
-{
- return m_timer.interval();
-}
-
-/*!
- Set the current launch interval to \a interval milliseconds
-*/
-
-void PrelaunchProcessBackendFactory::setLaunchInterval(int interval)
-{
- if (m_timer.interval() != interval) {
- bool active = m_timer.isActive();
- m_timer.stop();
- m_timer.setInterval(interval);
- if (active)
- startPrelaunchTimer();
- emit launchIntervalChanged();
- }
-}
-
-/*!
Returns whether prelaunching is enabled for this factory.
*/
bool PrelaunchProcessBackendFactory::prelaunchEnabled() const
@@ -199,7 +164,7 @@ void PrelaunchProcessBackendFactory::setPrelaunchEnabled(bool value)
if (m_prelaunchEnabled != value) {
m_prelaunchEnabled = value;
if (!m_prelaunchEnabled) {
- m_timer.stop();
+ setIdleCpuRequest(false);
if (m_prelaunch) {
m_prelaunch->deleteLater();
m_prelaunch = NULL;
@@ -226,7 +191,7 @@ bool PrelaunchProcessBackendFactory::hasPrelaunchedProcess() const
void PrelaunchProcessBackendFactory::handleMemoryRestrictionChange()
{
if (m_memoryRestricted) {
- m_timer.stop();
+ setIdleCpuRequest(false);
if (m_prelaunch) {
delete m_prelaunch; // This will kill the child process as well
m_prelaunch = NULL;
@@ -247,22 +212,21 @@ PrelaunchProcessBackend *PrelaunchProcessBackendFactory::prelaunchProcessBackend
/*!
Launch a new prelaunched process backend.
- In the future, it would be useful if the launch didn't require a timeout.
*/
-void PrelaunchProcessBackendFactory::timeout()
+void PrelaunchProcessBackendFactory::idleCpuAvailable()
{
- Q_ASSERT(m_prelaunch == NULL);
- Q_ASSERT(!m_memoryRestricted);
- Q_ASSERT(m_info);
-
- m_prelaunch = new PrelaunchProcessBackend(*m_info, this);
- connect(m_prelaunch, SIGNAL(finished(int,QProcess::ExitStatus)),
- SLOT(prelaunchFinished(int,QProcess::ExitStatus)));
- connect(m_prelaunch, SIGNAL(error(QProcess::ProcessError)),
- SLOT(prelaunchError(QProcess::ProcessError)));
- m_prelaunch->prestart();
- emit processPrelaunched();
+ if (!m_prelaunch && !m_memoryRestricted && m_info) {
+ setIdleCpuRequest(false); // Might delay this until the prelaunch is done....
+
+ m_prelaunch = new PrelaunchProcessBackend(*m_info, this);
+ connect(m_prelaunch, SIGNAL(finished(int,QProcess::ExitStatus)),
+ SLOT(prelaunchFinished(int,QProcess::ExitStatus)));
+ connect(m_prelaunch, SIGNAL(error(QProcess::ProcessError)),
+ SLOT(prelaunchError(QProcess::ProcessError)));
+ m_prelaunch->prestart();
+ emit processPrelaunched();
+ }
}
/*!
@@ -309,7 +273,7 @@ void PrelaunchProcessBackendFactory::prelaunchError(QProcess::ProcessError err)
void PrelaunchProcessBackendFactory::startPrelaunchTimer()
{
if (m_prelaunchEnabled)
- m_timer.start();
+ setIdleCpuRequest(true);
}
/*!
@@ -333,7 +297,7 @@ void PrelaunchProcessBackendFactory::setProcessInfo(ProcessInfo *processInfo)
}
startPrelaunchTimer();
} else {
- m_timer.stop();
+ setIdleCpuRequest(false);
}
emit processInfoChanged();
}
@@ -349,10 +313,6 @@ void PrelaunchProcessBackendFactory::setProcessInfo(ProcessInfo& processInfo)
/*!
- \fn void PrelaunchProcessBackendFactory::launchIntervalChanged()
- This signal is emitted when the launchInterval is changed.
- */
-/*!
\fn void PrelaunchProcessBackendFactory::processInfoChanged()
This signal is emitted when the internal ProcessInfo record is
changed.
diff --git a/src/core/prelaunchprocessbackendfactory.h b/src/core/prelaunchprocessbackendfactory.h
index 66c9923..4a5c0b5 100644
--- a/src/core/prelaunchprocessbackendfactory.h
+++ b/src/core/prelaunchprocessbackendfactory.h
@@ -42,7 +42,6 @@
#include "processbackendfactory.h"
#include "processmanager-global.h"
-#include <QTimer>
QT_BEGIN_NAMESPACE_PROCESSMANAGER
@@ -52,7 +51,6 @@ class PrelaunchProcessBackend;
class Q_ADDON_PROCESSMANAGER_EXPORT PrelaunchProcessBackendFactory : public ProcessBackendFactory
{
Q_OBJECT
- Q_PROPERTY(int launchInterval READ launchInterval WRITE setLaunchInterval NOTIFY launchIntervalChanged)
Q_PROPERTY(ProcessInfo* processInfo READ processInfo WRITE setProcessInfo NOTIFY processInfoChanged)
Q_PROPERTY(bool prelaunchEnabled READ prelaunchEnabled WRITE setPrelaunchEnabled NOTIFY prelaunchEnabledChanged)
@@ -69,16 +67,12 @@ public:
void setProcessInfo(ProcessInfo *processInfo);
void setProcessInfo(ProcessInfo& processInfo);
- int launchInterval() const;
- void setLaunchInterval(int interval);
-
bool prelaunchEnabled() const;
void setPrelaunchEnabled(bool value);
bool hasPrelaunchedProcess() const;
signals:
- void launchIntervalChanged();
void processInfoChanged();
void prelaunchEnabledChanged();
void processPrelaunched();
@@ -87,8 +81,10 @@ protected:
virtual void handleMemoryRestrictionChange();
PrelaunchProcessBackend *prelaunchProcessBackend() const;
+protected slots:
+ virtual void idleCpuAvailable();
+
private slots:
- void timeout();
void prelaunchFinished(int, QProcess::ExitStatus);
void prelaunchError(QProcess::ProcessError);
@@ -98,7 +94,6 @@ private:
private:
PrelaunchProcessBackend *m_prelaunch;
ProcessInfo *m_info;
- QTimer m_timer;
bool m_prelaunchEnabled;
};
diff --git a/src/core/processbackendfactory.cpp b/src/core/processbackendfactory.cpp
index b676789..17be8d5 100644
--- a/src/core/processbackendfactory.cpp
+++ b/src/core/processbackendfactory.cpp
@@ -41,6 +41,8 @@
#include "matchdelegate.h"
#include "rewritedelegate.h"
+#include <QDebug>
+
QT_BEGIN_NAMESPACE_PROCESSMANAGER
/*!
@@ -61,6 +63,11 @@ QT_BEGIN_NAMESPACE_PROCESSMANAGER
*/
/*!
+ \property ProcessBackendFactory::idleCpuRequest
+ \brief A boolean value indicating that this factory would like idle CPU cycles
+*/
+
+/*!
Construct a ProcessBackendFactory with an optional \a parent.
*/
@@ -69,6 +76,7 @@ ProcessBackendFactory::ProcessBackendFactory(QObject *parent)
, m_matchDelegate(NULL)
, m_rewriteDelegate(NULL)
, m_memoryRestricted(false)
+ , m_idleCpuRequest(false)
{
}
@@ -87,9 +95,9 @@ ProcessBackendFactory::~ProcessBackendFactory()
void ProcessBackendFactory::setMemoryRestricted(bool memoryRestricted)
{
- if (memoryRestricted != m_memoryRestricted) {
- m_memoryRestricted = memoryRestricted;
- handleMemoryRestrictionChange();
+ if (m_memoryRestricted != memoryRestricted) {
+ m_memoryRestricted = memoryRestricted;
+ handleMemoryRestrictionChange();
}
}
@@ -132,7 +140,8 @@ void ProcessBackendFactory::setMatchDelegate(MatchDelegate *matchDelegate)
if (m_matchDelegate)
delete m_matchDelegate;
m_matchDelegate = matchDelegate;
- m_matchDelegate->setParent(this);
+ if (m_matchDelegate)
+ m_matchDelegate->setParent(this);
emit matchDelegateChanged();
}
}
@@ -157,12 +166,44 @@ void ProcessBackendFactory::setRewriteDelegate(RewriteDelegate *rewriteDelegate)
if (m_rewriteDelegate)
delete m_rewriteDelegate;
m_rewriteDelegate = rewriteDelegate;
- m_rewriteDelegate->setParent(this);
+ if (m_rewriteDelegate)
+ m_rewriteDelegate->setParent(this);
emit rewriteDelegateChanged();
}
}
/*!
+ Return true if the factory is requesting idle CPU cycles
+ */
+
+bool ProcessBackendFactory::idleCpuRequest() const
+{
+ return m_idleCpuRequest;
+}
+
+/*!
+ Set the current idle CPU request value to \a value
+ */
+
+void ProcessBackendFactory::setIdleCpuRequest(bool value)
+{
+ if (value != m_idleCpuRequest) {
+ m_idleCpuRequest = value;
+ emit idleCpuRequestChanged();
+ }
+}
+
+/*!
+ This virtual function gets called when idle CPU is available.
+ Subclasses should override this function.
+ */
+
+void ProcessBackendFactory::idleCpuAvailable()
+{
+ qDebug() << Q_FUNC_INFO;
+}
+
+/*!
\fn bool ProcessBackendFactory::canCreate(const ProcessInfo& info) const
Return true if this ProcessBackendFactory matches the ProcessInfo \a info
@@ -208,6 +249,12 @@ void ProcessBackendFactory::rewrite(ProcessInfo& info)
*/
/*!
+ \fn void ProcessBackendFactory::idleCpuRequestChanged()
+
+ Signal emitted whenever the idle CPU request is changed
+*/
+
+/*!
\fn ProcessBackend * ProcessBackendFactory::create(const ProcessInfo& info, QObject *parent)
Create a ProcessBackend object based on the ProcessInfo \a info and \a parent.
diff --git a/src/core/processbackendfactory.h b/src/core/processbackendfactory.h
index 3600ed7..ed17d61 100644
--- a/src/core/processbackendfactory.h
+++ b/src/core/processbackendfactory.h
@@ -57,6 +57,7 @@ class Q_ADDON_PROCESSMANAGER_EXPORT ProcessBackendFactory : public QObject
Q_OBJECT
Q_PROPERTY(MatchDelegate* matchDelegate READ matchDelegate WRITE setMatchDelegate NOTIFY matchDelegateChanged);
Q_PROPERTY(RewriteDelegate* rewriteDelegate READ rewriteDelegate WRITE setRewriteDelegate NOTIFY rewriteDelegateChanged);
+ Q_PROPERTY(bool idleCpuRequest READ idleCpuRequest NOTIFY idleCpuRequestChanged)
public:
ProcessBackendFactory(QObject *parent = 0);
@@ -70,20 +71,27 @@ public:
MatchDelegate * matchDelegate() const;
void setMatchDelegate(MatchDelegate *);
+
RewriteDelegate * rewriteDelegate() const;
void setRewriteDelegate(RewriteDelegate *);
+ bool idleCpuRequest() const;
+ virtual void idleCpuAvailable();
+
signals:
void matchDelegateChanged();
void rewriteDelegateChanged();
+ void idleCpuRequestChanged();
protected:
virtual void handleMemoryRestrictionChange();
+ virtual void setIdleCpuRequest(bool);
protected:
MatchDelegate *m_matchDelegate;
RewriteDelegate *m_rewriteDelegate;
bool m_memoryRestricted;
+ bool m_idleCpuRequest;
};
QT_END_NAMESPACE_PROCESSMANAGER
diff --git a/src/core/processbackendmanager.cpp b/src/core/processbackendmanager.cpp
index 9e00602..5b1b414 100644
--- a/src/core/processbackendmanager.cpp
+++ b/src/core/processbackendmanager.cpp
@@ -40,6 +40,7 @@
#include "processbackendmanager.h"
#include "processbackendfactory.h"
#include "processbackend.h"
+#include "timeoutidledelegate.h"
QT_BEGIN_NAMESPACE_PROCESSMANAGER
@@ -69,16 +70,65 @@ QT_BEGIN_NAMESPACE_PROCESSMANAGER
The backend manager does not get involved in starting or tracking
the lifetime of a process. In general, you should use the
ProcessManager class for processes, which contains a backend manager object.
+
+ You may assign an IdleDelegate to the process manager. Certain factory
+ objects required processing time to launch prelaunched runtime processes.
+ An IdleDelegate is a class that lets the process manager know when the
+ system load is low so that the prelaunch programs can be started. If
+ 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
+ used by default.
+
+ If you prefer to not use delegates, you can subclass ProcessBackendManager
+ and override the \l{handleIdleCpuRequest()} function. If you do this,
+ you must shut off the default IdleDelegate. For example:
+
+ \code
+ class MyManager : public ProcessBackendManager {
+ public
+ MyManager(QObject *parent=0) : ProcessBackendManager(parent) {
+ setIdleDelegate(0);
+ connect(&timer, SIGNAL(timeout()), SLOT(checkCpuLoad()));
+ timer.setInterval(1000);
+ }
+
+ protected:
+ virtual void handleIdleCputRequest(bool request) {
+ if (request) timer.start();
+ else timer.stop();
+ }
+
+ protected slots:
+ void checkCpuLoad() {
+ if (calcCpuLoad() < 50)
+ idleCpuAvailable(); // Call the Idle CPU function
+ }
+
+ private:
+ QTimer timer;
+ }
+ \endcode
+*/
+
+/*!
+ \property ProcessBackendManager::idleDelegate
+ \brief The IdleDelegate object assigned to this factory.
*/
/*!
Construct a ProcessBackendManager with an optional \a parent
+ By default, a TimeoutIdleDelegate is assigned to the idleDelegate.
*/
ProcessBackendManager::ProcessBackendManager(QObject *parent)
: QObject(parent)
, m_memoryRestricted(false)
+ , m_idleCpuRequest(false)
{
+ m_idleDelegate = new TimeoutIdleDelegate(this);
+ connect(m_idleDelegate, SIGNAL(idleCpuAvailable()), SLOT(idleCpuAvailable()));
}
/*!
@@ -115,6 +165,8 @@ void ProcessBackendManager::addFactory(ProcessBackendFactory *factory)
m_factories.append(factory);
factory->setParent(this);
factory->setMemoryRestricted(m_memoryRestricted);
+ connect(factory, SIGNAL(idleCpuRequestChanged()), SLOT(updateIdleCpuRequest()));
+ updateIdleCpuRequest();
}
/*!
@@ -123,10 +175,10 @@ void ProcessBackendManager::addFactory(ProcessBackendFactory *factory)
QList<Q_PID> ProcessBackendManager::internalProcesses()
{
- QList<Q_PID> list;
+ QList<Q_PID> plist;
foreach (ProcessBackendFactory *factory, m_factories)
- list.append(factory->internalProcesses());
- return list;
+ plist.append(factory->internalProcesses());
+ return plist;
}
/*!
@@ -137,9 +189,10 @@ QList<Q_PID> ProcessBackendManager::internalProcesses()
void ProcessBackendManager::setMemoryRestricted(bool memoryRestricted)
{
if (m_memoryRestricted != memoryRestricted) {
- m_memoryRestricted = memoryRestricted;
- foreach (ProcessBackendFactory *factory, m_factories)
- factory->setMemoryRestricted(memoryRestricted);
+ m_memoryRestricted = memoryRestricted;
+ foreach (ProcessBackendFactory *factory, m_factories) {
+ factory->setMemoryRestricted(memoryRestricted);
+ }
}
}
@@ -152,6 +205,90 @@ bool ProcessBackendManager::memoryRestricted() const
return m_memoryRestricted;
}
+/*!
+ Return the current IdleDelegate object
+ */
+
+IdleDelegate *ProcessBackendManager::idleDelegate() const
+{
+ return m_idleDelegate;
+}
+
+/*!
+ Set a new process IdleDelegate object \a idleDelegate.
+ The ProcessBackendManager takes over parentage of the IdleDelegate.
+ */
+
+void ProcessBackendManager::setIdleDelegate(IdleDelegate *idleDelegate)
+{
+ if (idleDelegate != m_idleDelegate) {
+ if (m_idleDelegate)
+ delete m_idleDelegate;
+ m_idleDelegate = idleDelegate;
+ if (m_idleDelegate) {
+ m_idleDelegate->setParent(this);
+ connect(m_idleDelegate, SIGNAL(idleCpuAvailable()), SLOT(idleCpuAvailable()));
+ }
+ emit idleDelegateChanged();
+ m_idleCpuRequest = false; // Force this to be recalculated
+ updateIdleCpuRequest();
+ }
+}
+
+/*!
+ \fn bool ProcessBackendManager::idleCpuRequest() const
+ Return \c{true} if we need idle CPU cycles.
+ */
+
+/*!
+ Idle CPU processing is available. This function distributes
+ the idle CPU to the first factory that has requested it.
+ */
+
+void ProcessBackendManager::idleCpuAvailable()
+{
+ foreach (ProcessBackendFactory *factory, m_factories) {
+ if (factory->idleCpuRequest()) {
+ factory->idleCpuAvailable();
+ return;
+ }
+ }
+}
+
+/*!
+ Update the current idle cpu request status by polling
+ the factories.
+ */
+
+void ProcessBackendManager::updateIdleCpuRequest()
+{
+ bool request = false;
+ foreach (ProcessBackendFactory *factory, m_factories)
+ request |= factory->idleCpuRequest();
+
+ if (request != m_idleCpuRequest) {
+ m_idleCpuRequest = request;
+ if (m_idleDelegate)
+ m_idleDelegate->requestIdleCpu(m_idleCpuRequest);
+ handleIdleCpuRequest(m_idleCpuRequest);
+ }
+}
+
+/*!
+ Override this function to customize your handling of Idle CPU requests.
+ The \a request variable will be \c{true} if Idle CPU events are needed.
+ */
+
+void ProcessBackendManager::handleIdleCpuRequest(bool request)
+{
+ Q_UNUSED(request);
+}
+
+/*!
+ \fn void ProcessBackendManager::idleDelegateChanged()
+ Signal emitted whenever the IdleDelegate is changed.
+*/
+
#include "moc_processbackendmanager.cpp"
QT_END_NAMESPACE_PROCESSMANAGER
diff --git a/src/core/processbackendmanager.h b/src/core/processbackendmanager.h
index 7bae695..c976cb3 100644
--- a/src/core/processbackendmanager.h
+++ b/src/core/processbackendmanager.h
@@ -52,10 +52,12 @@ class ProcessFrontend;
class ProcessInfo;
class ProcessBackendFactory;
class ProcessBackend;
+class IdleDelegate;
class Q_ADDON_PROCESSMANAGER_EXPORT ProcessBackendManager : public QObject
{
Q_OBJECT
+ Q_PROPERTY(IdleDelegate* idleDelegate READ idleDelegate WRITE setIdleDelegate NOTIFY idleDelegateChanged);
public:
explicit ProcessBackendManager(QObject *parent = 0);
@@ -68,9 +70,27 @@ public:
void setMemoryRestricted(bool);
bool memoryRestricted() const;
+ IdleDelegate * idleDelegate() const;
+ void setIdleDelegate(IdleDelegate *);
+ bool idleCpuRequest() const { return m_idleCpuRequest; }
+
+protected:
+ virtual void handleIdleCpuRequest(bool request);
+
+signals:
+ void idleDelegateChanged();
+
+protected slots:
+ void idleCpuAvailable();
+
+private slots:
+ void updateIdleCpuRequest();
+
private:
QList<ProcessBackendFactory*> m_factories;
+ IdleDelegate *m_idleDelegate;
bool m_memoryRestricted;
+ bool m_idleCpuRequest;
};
QT_END_NAMESPACE_PROCESSMANAGER
diff --git a/src/core/timeoutidledelegate.cpp b/src/core/timeoutidledelegate.cpp
new file mode 100644
index 0000000..eeb814e
--- /dev/null
+++ b/src/core/timeoutidledelegate.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "timeoutidledelegate.h"
+
+QT_BEGIN_NAMESPACE_PROCESSMANAGER
+
+const int kIdleTimerInterval = 1000;
+
+/*!
+ \class TimeoutIdleDelegate
+ \brief The TimeoutIdleDelegate class generates a periodic timeout.
+
+ The TimeoutIdleDelegate class generates a periodic timeout for
+ creation of idle resources. This is not an intelligent class - it
+ doesn't matter what your CPU is doing, it will still generate the
+ periodic timeout.
+*/
+
+/*!
+ \property TimeoutIdleDelegate::idleInterval
+ \brief Time in milliseconds before a new idle CPU request will be fulfilled
+ */
+
+
+/*!
+ Construct a TimeoutIdleDelegate with an optional \a parent.
+*/
+
+TimeoutIdleDelegate::TimeoutIdleDelegate(QObject *parent)
+ : IdleDelegate(parent)
+{
+ connect(&m_timer, SIGNAL(timeout()), SIGNAL(idleCpuAvailable()));
+ m_timer.setInterval(kIdleTimerInterval);
+}
+
+/*!
+ \fn void TimeoutIdleDelegate::requestIdleCpu(bool request)
+
+ Turn on or off idle requests based on \a request
+ You must override this function in a subclass.
+*/
+
+void TimeoutIdleDelegate::requestIdleCpu(bool request)
+{
+ if (request != m_timer.isActive()) {
+ if (request)
+ m_timer.start();
+ else
+ m_timer.stop();
+ }
+}
+
+/*!
+ Return the current launch interval in milliseconds
+ */
+
+int TimeoutIdleDelegate::idleInterval() const
+{
+ return m_timer.interval();
+}
+
+/*!
+ Set the current idle interval to \a interval milliseconds
+*/
+
+void TimeoutIdleDelegate::setIdleInterval(int interval)
+{
+ if (m_timer.interval() != interval) {
+ bool active = m_timer.isActive();
+ m_timer.stop();
+ m_timer.setInterval(interval);
+ if (active)
+ m_timer.start();
+ emit idleIntervalChanged();
+ }
+}
+
+/*!
+ \fn void TimeoutIdleDelegate::idleIntervalChanged()
+ This signal is emitted when the idleInterval is changed.
+ */
+
+
+#include "moc_timeoutidledelegate.cpp"
+
+QT_END_NAMESPACE_PROCESSMANAGER
diff --git a/src/core/timeoutidledelegate.h b/src/core/timeoutidledelegate.h
new file mode 100644
index 0000000..98199a8
--- /dev/null
+++ b/src/core/timeoutidledelegate.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TIMEOUT_IDLE_DELEGATE_H
+#define TIMEOUT_IDLE_DELEGATE_H
+
+#include <QTimer>
+#include "idledelegate.h"
+
+QT_BEGIN_NAMESPACE_PROCESSMANAGER
+
+class ProcessInfo;
+
+class Q_ADDON_PROCESSMANAGER_EXPORT TimeoutIdleDelegate : public IdleDelegate
+{
+ Q_OBJECT
+ Q_PROPERTY(int idleInterval READ idleInterval WRITE setIdleInterval NOTIFY idleIntervalChanged)
+
+public:
+ explicit TimeoutIdleDelegate(QObject *parent = 0);
+ virtual void requestIdleCpu(bool request);
+
+ int idleInterval() const;
+ void setIdleInterval(int interval);
+
+signals:
+ void idleIntervalChanged();
+
+private:
+ Q_DISABLE_COPY(TimeoutIdleDelegate);
+ QTimer m_timer;
+};
+
+QT_END_NAMESPACE_PROCESSMANAGER
+
+#endif // TIMEOUT_IDLE_DELEGATE_H
diff --git a/tests/auto/processmanager/tst_processmanager.cpp b/tests/auto/processmanager/tst_processmanager.cpp
index cd1a3a4..3ea570e 100644
--- a/tests/auto/processmanager/tst_processmanager.cpp
+++ b/tests/auto/processmanager/tst_processmanager.cpp
@@ -53,6 +53,7 @@
#include "qjsondocument.h"
#include "pipeprocessbackendfactory.h"
#include "socketprocessbackendfactory.h"
+#include "timeoutidledelegate.h"
#include <signal.h>
@@ -979,13 +980,15 @@ void tst_ProcessManager::prelaunchChildAbort()
// The factory should not have launched
QVERIFY(manager->internalProcesses().count() == 0);
+ TimeoutIdleDelegate *delegate = qobject_cast<TimeoutIdleDelegate *>(manager->idleDelegate());
+ QVERIFY(delegate);
- waitForInternalProcess(manager, 1, factory->launchInterval() + 2000);
+ waitForInternalProcess(manager, 1, delegate->idleInterval() + 2000);
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, factory->launchInterval() + 2000);
+ waitForInternalProcess(manager, 1, delegate->idleInterval() + 2000);
delete manager;
}
diff --git a/tests/manual/cpuload/.gitignore b/tests/manual/cpuload/.gitignore
new file mode 100644
index 0000000..9613bc1
--- /dev/null
+++ b/tests/manual/cpuload/.gitignore
@@ -0,0 +1 @@
+tst_cpuload
diff --git a/tests/manual/cpuload/cpuload.pro b/tests/manual/cpuload/cpuload.pro
new file mode 100644
index 0000000..d6b9897
--- /dev/null
+++ b/tests/manual/cpuload/cpuload.pro
@@ -0,0 +1,7 @@
+TEMPLATE = app
+TARGET = tst_cpuload
+CONFIG -= app_bundle
+QT += processmanager
+QT -= gui
+
+SOURCES = tst_cpuload.cpp
diff --git a/tests/manual/cpuload/tst_cpuload.cpp b/tests/manual/cpuload/tst_cpuload.cpp
new file mode 100644
index 0000000..4037931
--- /dev/null
+++ b/tests/manual/cpuload/tst_cpuload.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+#include <QStringList>
+#include <QDebug>
+
+#include <cpuidledelegate.h>
+#include <iostream>
+
+QT_USE_NAMESPACE_PROCESSMANAGER
+
+QString progname;
+
+class Target : public QObject {
+ Q_OBJECT
+
+public slots:
+ void loadUpdate(double value) {
+ std::cout << value << std::endl;
+ }
+ void idleCpuAvailable() {
+ std::cout << "idle ";
+ }
+};
+
+static void usage()
+{
+ qWarning("Usage: %s [ARGS]\n", qPrintable(progname));
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+ QStringList args = QCoreApplication::arguments();
+ progname = args.takeFirst();
+ while (args.size()) {
+ QString arg = args.at(0);
+ if (!arg.startsWith('-'))
+ break;
+ args.removeFirst();
+ if (arg == QLatin1String("-help"))
+ usage();
+ }
+
+ if (args.size())
+ usage();
+
+ CpuIdleDelegate cpu;
+ Target t;
+ QObject::connect(&cpu, SIGNAL(loadUpdate(double)), &t, SLOT(loadUpdate(double)));
+ QObject::connect(&cpu, SIGNAL(idleCpuAvailable()), &t, SLOT(idleCpuAvailable()));
+
+ cpu.requestIdleCpu(true);
+ return app.exec();
+}
+
+#include "tst_cpuload.moc"