summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Christian <andrew.christian@nokia.com>2012-02-08 12:52:17 -0500
committerChris Craig <ext-chris.craig@nokia.com>2012-02-08 22:37:30 +0100
commit1b55e397a94ad39adaaf21276a74605ea999ab1a (patch)
tree4bb9a99e801abf88caa7688f09358efdd325726e
parent458c47468386fa51c20f862561d50dcbd05da15b (diff)
Updating prelaunch backend factory.
* Factory now restarts a failed prelaunched process. * Factory has "launchInterval" property to allow changing how frequently the prelaunched process is started. Change-Id: I870222b7d4b8a893477c254be72277e0380be5d6 Reviewed-by: Chris Craig <ext-chris.craig@nokia.com>
-rw-r--r--src/core/prelaunchprocessbackend.cpp20
-rw-r--r--src/core/prelaunchprocessbackendfactory.cpp48
-rw-r--r--src/core/prelaunchprocessbackendfactory.h9
-rw-r--r--tests/auto/processmanager/tst_processmanager.cpp32
4 files changed, 92 insertions, 17 deletions
diff --git a/src/core/prelaunchprocessbackend.cpp b/src/core/prelaunchprocessbackend.cpp
index 27142f5..f855af4 100644
--- a/src/core/prelaunchprocessbackend.cpp
+++ b/src/core/prelaunchprocessbackend.cpp
@@ -167,13 +167,12 @@ QProcess::ProcessState PrelaunchProcessBackend::state() const
void PrelaunchProcessBackend::handleProcessStarted()
{
UnixProcessBackend::handleProcessStarted();
- if (m_started)
- emit started();
- else {
+ if (!m_started) {
QueuedSignal s;
s.name = QueuedSignal::Started;
m_queue << s;
}
+ emit started();
}
/*!
@@ -182,14 +181,13 @@ void PrelaunchProcessBackend::handleProcessStarted()
void PrelaunchProcessBackend::handleProcessError(QProcess::ProcessError processError)
{
UnixProcessBackend::handleProcessError(processError);
- if (m_started)
- emit error(processError);
- else {
+ if (!m_started) {
QueuedSignal s;
s.name = QueuedSignal::Error;
s.n.error = processError;
m_queue << s;
}
+ emit error(processError);
}
/*!
@@ -198,15 +196,14 @@ void PrelaunchProcessBackend::handleProcessError(QProcess::ProcessError processE
void PrelaunchProcessBackend::handleProcessFinished(int exitCode, QProcess::ExitStatus status)
{
UnixProcessBackend::handleProcessFinished(exitCode, status);
- if (m_started)
- emit finished(exitCode, status);
- else {
+ if (!m_started) {
QueuedSignal s;
s.name = QueuedSignal::Finished;
s.n.f.exitCode = exitCode;
s.n.f.exitStatus = status;
m_queue << s;
}
+ emit finished(exitCode, status);
}
/*!
@@ -215,14 +212,13 @@ void PrelaunchProcessBackend::handleProcessFinished(int exitCode, QProcess::Exit
void PrelaunchProcessBackend::handleProcessStateChanged(QProcess::ProcessState state)
{
UnixProcessBackend::handleProcessStateChanged(state);
- if (m_started)
- emit stateChanged(state);
- else {
+ if (!m_started) {
QueuedSignal s;
s.name = QueuedSignal::StateChanged;
s.n.state = state;
m_queue << s;
}
+ emit stateChanged(state);
}
/*!
diff --git a/src/core/prelaunchprocessbackendfactory.cpp b/src/core/prelaunchprocessbackendfactory.cpp
index ccb5a1f..33a20b5 100644
--- a/src/core/prelaunchprocessbackendfactory.cpp
+++ b/src/core/prelaunchprocessbackendfactory.cpp
@@ -107,6 +107,7 @@ ProcessBackend * PrelaunchProcessBackendFactory::create(const ProcessInfo& info,
m_timer.start();
prelaunch->setInfo(info);
prelaunch->setParent(parent);
+ prelaunch->disconnect(this);
}
else {
// qDebug() << "Creating prelaunch from scratch";
@@ -130,6 +131,31 @@ QList<Q_PID> PrelaunchProcessBackendFactory::internalProcesses()
}
/*!
+ 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)
+ m_timer.start();
+ emit launchIntervalChanged();
+ }
+}
+
+/*!
Under memory restriction, terminate the prelaunch process.
*/
@@ -147,15 +173,37 @@ void PrelaunchProcessBackendFactory::handleMemoryRestrictionChange()
}
}
+/*!
+ Launch a new prelaunched process backend.
+ In the future, it would be useful if the launch didn't require a timeout.
+ */
+
void PrelaunchProcessBackendFactory::timeout()
{
Q_ASSERT(m_prelaunch == NULL);
Q_ASSERT(!m_memoryRestricted);
m_prelaunch = new PrelaunchProcessBackend(m_info, this);
+ connect(m_prelaunch, SIGNAL(finished(int,QProcess::ExitStatus)),
+ SLOT(prelaunchFinished(int,QProcess::ExitStatus)));
m_prelaunch->prestart();
}
+/*!
+ Handle a surprise termination condition - the prelaunched process died
+ unexpectedly.
+ */
+
+void PrelaunchProcessBackendFactory::prelaunchFinished(int exitCode, QProcess::ExitStatus status)
+{
+ qWarning() << Q_FUNC_INFO << "died unexpectedly" << exitCode << status;
+ if (m_prelaunch) {
+ delete m_prelaunch;
+ m_prelaunch = NULL;
+ }
+ m_timer.start();
+}
+
#include "moc_prelaunchprocessbackendfactory.cpp"
QT_END_NAMESPACE_PROCESSMANAGER
diff --git a/src/core/prelaunchprocessbackendfactory.h b/src/core/prelaunchprocessbackendfactory.h
index 3f1d087..5702b77 100644
--- a/src/core/prelaunchprocessbackendfactory.h
+++ b/src/core/prelaunchprocessbackendfactory.h
@@ -52,6 +52,8 @@ class PrelaunchProcessBackend;
class Q_ADDON_PROCESSMANAGER_EXPORT PrelaunchProcessBackendFactory : public ProcessBackendFactory
{
Q_OBJECT
+ Q_PROPERTY(int launchInterval READ launchInterval WRITE setLaunchInterval NOTIFY launchIntervalChanged)
+
public:
PrelaunchProcessBackendFactory(const ProcessInfo& info, QObject *parent = 0);
virtual ~PrelaunchProcessBackendFactory();
@@ -60,11 +62,18 @@ public:
virtual QList<Q_PID> internalProcesses();
+ int launchInterval() const;
+ void setLaunchInterval(int interval);
+
+signals:
+ void launchIntervalChanged();
+
protected:
virtual void handleMemoryRestrictionChange();
private slots:
void timeout();
+ void prelaunchFinished(int, QProcess::ExitStatus);
private:
PrelaunchProcessBackend *m_prelaunch;
diff --git a/tests/auto/processmanager/tst_processmanager.cpp b/tests/auto/processmanager/tst_processmanager.cpp
index ee9d276..cc35e89 100644
--- a/tests/auto/processmanager/tst_processmanager.cpp
+++ b/tests/auto/processmanager/tst_processmanager.cpp
@@ -56,6 +56,8 @@
#include "pipeprocessbackendfactory.h"
#include "socketprocessbackendfactory.h"
+#include <signal.h>
+
QT_USE_NAMESPACE_PROCESSMANAGER
Q_DECLARE_METATYPE(QProcess::ExitStatus);
@@ -138,7 +140,7 @@ bool isProcessStopped(Q_PID pid)
return false;
}
-static void waitForInternalProcess(ProcessBackendManager *manager, int timeout=5000)
+static void waitForInternalProcess(ProcessBackendManager *manager, int num=1, int timeout=5000)
{
QTime stopWatch;
stopWatch.start();
@@ -146,7 +148,7 @@ static void waitForInternalProcess(ProcessBackendManager *manager, int timeout=5
QTestEventLoop::instance().enterLoop(1);
if (stopWatch.elapsed() >= timeout)
QFAIL("Timed out");
- if (manager->internalProcesses().count() == 1)
+ if (manager->internalProcesses().count() == num)
break;
}
}
@@ -713,6 +715,8 @@ private slots:
void socketLauncherOomChangeAfter() { socketLauncherTest(oomChangeAfterClient); }
#endif
+ void prelaunchChildAbort();
+
void frontend();
void subclassFrontend();
};
@@ -999,11 +1003,30 @@ void tst_ProcessManager::socketLauncherCrash()
delete remote;
}
- */
+*/
+
+void tst_ProcessManager::prelaunchChildAbort()
+{
+ ProcessBackendManager *manager = new ProcessBackendManager;
+ ProcessInfo info;
+ info.setValue("program", "testPrelaunch/testPrelaunch");
+ PrelaunchProcessBackendFactory *factory = new PrelaunchProcessBackendFactory(info);
+ manager->addFactory(factory);
+
+ // The factory should not have launched
+ QVERIFY(manager->internalProcesses().count() == 0);
+
+ waitForInternalProcess(manager, 1, factory->launchInterval() + 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);
+ delete manager;
+}
void tst_ProcessManager::frontend()
{
- QString socketname = "/tmp/tst_socket";
ProcessManager *manager = new ProcessManager;
manager->addBackendFactory(new StandardProcessBackendFactory);
@@ -1061,7 +1084,6 @@ private:
void tst_ProcessManager::subclassFrontend()
{
- QString socketname = "/tmp/tst_socket";
TestManager *manager = new TestManager;
manager->addBackendFactory(new StandardProcessBackendFactory);