summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Christian <andrew.christian@nokia.com>2012-03-05 12:09:58 -0500
committerLasse Holmstedt <lasse.holmstedt@nokia.com>2012-03-05 18:22:53 +0100
commitea7d7e8cf0bc03c80c46051ce19d69bafa59504f (patch)
treed59022d8db77344b6b78e8b75eef26c22dbf05de
parent7c5c9b19c32255164b991d3840f92d88b86fbed5 (diff)
Update prelaunch to copy processinfo record.
* Added declarative test cases for Prelaunch factory * Copy ProcessInfo record into prelaunch factory to avoid memory management issues Change-Id: I3303286f34c7ee9c491a82726e4e4b50892625e4 Reviewed-by: Lasse Holmstedt <lasse.holmstedt@nokia.com>
-rw-r--r--src/core/prelaunchprocessbackendfactory.cpp49
-rw-r--r--src/core/prelaunchprocessbackendfactory.h2
-rw-r--r--tests/auto/declarative/data/testprelaunch.qml42
-rw-r--r--tests/auto/declarative/tst_declarative.cpp9
-rw-r--r--tests/auto/processmanager/tst_processmanager.cpp31
5 files changed, 111 insertions, 22 deletions
diff --git a/src/core/prelaunchprocessbackendfactory.cpp b/src/core/prelaunchprocessbackendfactory.cpp
index de48f18..f7eb263 100644
--- a/src/core/prelaunchprocessbackendfactory.cpp
+++ b/src/core/prelaunchprocessbackendfactory.cpp
@@ -68,7 +68,7 @@ const int kPrelaunchTimerInterval = 1000;
PrelaunchProcessBackendFactory::PrelaunchProcessBackendFactory(QObject *parent)
: ProcessBackendFactory(parent)
, m_prelaunch(NULL)
- , m_info(0)
+ , m_info(NULL)
, m_prelaunchEnabled(true)
{
connect(&m_timer, SIGNAL(timeout()), SLOT(timeout()));
@@ -228,6 +228,8 @@ void PrelaunchProcessBackendFactory::timeout()
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();
}
@@ -241,13 +243,36 @@ void PrelaunchProcessBackendFactory::prelaunchFinished(int exitCode, QProcess::E
{
qWarning() << Q_FUNC_INFO << "died unexpectedly" << exitCode << status;
if (m_prelaunch) {
- delete m_prelaunch;
+ m_prelaunch->deleteLater();
m_prelaunch = NULL;
}
startPrelaunchTimer();
}
/*!
+ Handle surprise error conditions on the prelaunched process.
+ */
+
+void PrelaunchProcessBackendFactory::prelaunchError(QProcess::ProcessError err)
+{
+ qWarning() << Q_FUNC_INFO << "unexpected error" << err;
+ if (m_prelaunch) {
+ m_prelaunch->deleteLater();
+ m_prelaunch = NULL;
+ }
+
+ if (err == QProcess::FailedToStart) {
+ qWarning() << Q_FUNC_INFO << "disabling prelaunch because of process errors";
+ m_prelaunchEnabled = false;
+
+ }
+ else {
+ // ### TODO: This isn't optimal
+ startPrelaunchTimer();
+ }
+}
+
+/*!
Starts the prelaunch timer only if prelaunching is enabled.
*/
void PrelaunchProcessBackendFactory::startPrelaunchTimer()
@@ -258,15 +283,18 @@ void PrelaunchProcessBackendFactory::startPrelaunchTimer()
/*!
Sets the ProcessInfo that is used to determine the prelaunched runtime to \a processInfo.
- Takes ownership of the object. If the ProcessInfo object is changed, the old object is deleted.
+ An internal copy is made of the \a processInfo object.
*/
void PrelaunchProcessBackendFactory::setProcessInfo(ProcessInfo *processInfo)
{
if (m_info != processInfo) {
- delete m_info;
- m_info = processInfo;
-
if (m_info) {
+ delete m_info;
+ m_info = NULL;
+ }
+
+ if (processInfo) {
+ m_info = new ProcessInfo(*processInfo);
m_info->setParent(this);
startPrelaunchTimer();
} else {
@@ -277,6 +305,15 @@ void PrelaunchProcessBackendFactory::setProcessInfo(ProcessInfo *processInfo)
}
/*!
+ Sets the ProcessInfo that is used to determine the prelaunched runtime to \a processInfo.
+ */
+void PrelaunchProcessBackendFactory::setProcessInfo(ProcessInfo& processInfo)
+{
+ setProcessInfo(&processInfo);
+}
+
+
+/*!
\fn void PrelaunchProcessBackendFactory::launchIntervalChanged()
This signal is emitted when the launchInterval is changed.
*/
diff --git a/src/core/prelaunchprocessbackendfactory.h b/src/core/prelaunchprocessbackendfactory.h
index 4c4be5a..66c9923 100644
--- a/src/core/prelaunchprocessbackendfactory.h
+++ b/src/core/prelaunchprocessbackendfactory.h
@@ -67,6 +67,7 @@ public:
ProcessInfo *processInfo() const;
void setProcessInfo(ProcessInfo *processInfo);
+ void setProcessInfo(ProcessInfo& processInfo);
int launchInterval() const;
void setLaunchInterval(int interval);
@@ -89,6 +90,7 @@ protected:
private slots:
void timeout();
void prelaunchFinished(int, QProcess::ExitStatus);
+ void prelaunchError(QProcess::ProcessError);
private:
void startPrelaunchTimer();
diff --git a/tests/auto/declarative/data/testprelaunch.qml b/tests/auto/declarative/data/testprelaunch.qml
new file mode 100644
index 0000000..a06cbbf
--- /dev/null
+++ b/tests/auto/declarative/data/testprelaunch.qml
@@ -0,0 +1,42 @@
+import QtQuick 2.0
+import Test 1.0
+
+DeclarativeProcessManager {
+ id: foo
+
+ factories: [
+ PrelaunchProcessBackendFactory {
+ id: foo3
+ processInfo: ProcessInfo {
+ program: "testDeclarative/testDeclarative"
+ }
+ }
+ ]
+
+ onProcessStarted: console.log("Process started "+name)
+ onProcessStateChanged: {
+ function stateToString(s) {
+ if (s == Process.NotRunning) return "Not running";
+ if (s == Process.Running) return "Running";
+ if (s == Process.Starting) return "Starting";
+ return "Unknown";
+ }
+ console.log("state changed for "+name+" to "+stateToString(state));
+ }
+
+ function makeProcess() {
+ var a = create({"program": "testDeclarative/testDeclarative","name": "test-client"});
+ return a.name;
+ }
+
+ function startProcess(name) {
+ var p = processForName(name);
+ console.log("Starting process '"+name+"' ="+p);
+ p.start();
+ }
+
+ function stopProcess(name) {
+ var p = processForName(name);
+ p.stop();
+ }
+}
diff --git a/tests/auto/declarative/tst_declarative.cpp b/tests/auto/declarative/tst_declarative.cpp
index f5b9167..68e5e6c 100644
--- a/tests/auto/declarative/tst_declarative.cpp
+++ b/tests/auto/declarative/tst_declarative.cpp
@@ -53,6 +53,7 @@
#include "declarativematchdelegate.h"
#include "declarativerewritedelegate.h"
#include "standardprocessbackendfactory.h"
+#include "prelaunchprocessbackendfactory.h"
#include "socketprocessbackendfactory.h"
#include "processfrontend.h"
#include "processbackend.h"
@@ -72,6 +73,7 @@ private slots:
void initTestCase();
void basic();
+ void prelaunch();
void matchDelegate();
void socketLauncher();
void socketRangeLauncher();
@@ -92,6 +94,8 @@ void tst_DeclarativeProcessManager::initTestCase()
qmlRegisterType<ProcessFrontend>();
qmlRegisterType<StandardProcessBackendFactory>(uri, 1, 0, "StandardProcessBackendFactory");
+ qmlRegisterType<PrelaunchProcessBackendFactory>(uri, 1, 0, "PrelaunchProcessBackendFactory");
+ qmlRegisterType<ProcessInfo>(uri, 1, 0, "ProcessInfo");
qmlRegisterType<SocketProcessBackendFactory>(uri, 1, 0, "SocketProcessBackendFactory");
qmlRegisterType<DeclarativeProcessManager>(uri, 1, 0, "DeclarativeProcessManager");
qmlRegisterType<DeclarativeMatchDelegate>(uri, 1, 0, "DeclarativeMatchDelegate");
@@ -246,6 +250,11 @@ void tst_DeclarativeProcessManager::basic()
_frontendTest("data/testfrontend.qml");
}
+void tst_DeclarativeProcessManager::prelaunch()
+{
+ _frontendTest("data/testprelaunch.qml");
+}
+
void tst_DeclarativeProcessManager::matchDelegate()
{
_frontendTest("data/testmatch.qml");
diff --git a/tests/auto/processmanager/tst_processmanager.cpp b/tests/auto/processmanager/tst_processmanager.cpp
index 56cea89..3cc2cf2 100644
--- a/tests/auto/processmanager/tst_processmanager.cpp
+++ b/tests/auto/processmanager/tst_processmanager.cpp
@@ -695,22 +695,21 @@ static void standardTest( clientFunc func, infoFunc infoFixup=0 )
static void prelaunchTest( clientFunc func, infoFunc infoFixup=0 )
{
ProcessBackendManager *manager = new ProcessBackendManager;
-
- QScopedPointer<ProcessInfo> info(new ProcessInfo);
- info->setValue("program", "testPrelaunch/testPrelaunch");
+ ProcessInfo info;
+ info.setValue("program", "testPrelaunch/testPrelaunch");
if (infoFixup)
- infoFixup(*info);
+ infoFixup(info);
PrelaunchProcessBackendFactory *factory = new PrelaunchProcessBackendFactory;
- factory->setProcessInfo(info.data());
+ factory->setProcessInfo(info);
manager->addFactory(factory);
// Verify that there is a prelaunched process
QVERIFY(manager->memoryRestricted() == false);
waitForInternalProcess(manager);
- fixUidGid(*info);
- func(manager, *info, writeJson);
+ fixUidGid(info);
+ func(manager, info, writeJson);
delete manager;
}
@@ -719,18 +718,18 @@ static void prelaunchRestrictedTest( clientFunc func, infoFunc infoFixup=0 )
ProcessBackendManager *manager = new ProcessBackendManager;
manager->setMemoryRestricted(true);
- QScopedPointer<ProcessInfo> info(new ProcessInfo);
- info->setValue("program", "testPrelaunch/testPrelaunch");
+ ProcessInfo info;
+ info.setValue("program", "testPrelaunch/testPrelaunch");
if (infoFixup)
- infoFixup(*info);
+ infoFixup(info);
PrelaunchProcessBackendFactory *factory = new PrelaunchProcessBackendFactory;
- factory->setProcessInfo(info.data());
+ factory->setProcessInfo(info);
manager->addFactory(factory);
QVERIFY(manager->memoryRestricted() == true);
- fixUidGid(*info);
- func(manager, *info, writeJson);
+ fixUidGid(info);
+ func(manager, info, writeJson);
delete manager;
}
@@ -925,10 +924,10 @@ void tst_ProcessManager::initTestCase()
void tst_ProcessManager::prelaunchChildAbort()
{
ProcessBackendManager *manager = new ProcessBackendManager;
- QScopedPointer<ProcessInfo> info(new ProcessInfo);
- info->setValue("program", "testPrelaunch/testPrelaunch");
+ ProcessInfo info;
+ info.setValue("program", "testPrelaunch/testPrelaunch");
PrelaunchProcessBackendFactory *factory = new PrelaunchProcessBackendFactory;
- factory->setProcessInfo(info.data());
+ factory->setProcessInfo(info);
manager->addFactory(factory);
// The factory should not have launched