[haiku-commits] BRANCH axeld-github.launch_daemon [955efcfea941] src/tests/servers/launch src/servers/launch src/apps/installer data/launch

  • From: axeld-github.launch_daemon <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 10 Jul 2015 17:16:52 +0200 (CEST)

added 6 changesets to branch 'refs/remotes/axeld-github/launch_daemon'
old head: da8df45beceeb7b904c8acd4e32c794967aa4adb
new head: 955efcfea94105eaaed1b1d948446fdd31bff37d
overview: https://github.com/axeld/haiku/compare/da8df45becee...955efcfea941

----------------------------------------------------------------------------

963f548e6b39: Installer: Unblock CD tray, and eject it, shutdown on quit.

* This was done in the Bootscript.cd before, but now the Installer
does it directly, but only in case the Deskbar is not running.

6e4aaae82c4f: launch_daemon: Fixed condition tests build.

* ConditionContext changed.

14ec22884cbd: launch_daemon: Added events parsing.

* Including tests, also for the environment parsing.

31e1780963ab: launch_daemon: Fixed a race condition in Worker startup.

* When the thread is started during the construction of the base
class, the virtual method table may still point to the methods
of the base class when the thread actually starts to run.
* This caused the main worker to have a timeout, which could
eventually be reached which in turn caused all job processing
to stop.
* That's what you get when you do Java all day; whoever designed
C++ should be slapped (I'm talking to you, Bjarne).

9e93bb57f3d1: launch_daemon: Improved error reporting, minor cleanup.

955efcfea941: Create installer link in live mode, check existence.

* FirstBootPrompt as well as the Installer do not exist on the
minimum image, so take this into account when making the startup
target decisions.

[ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

15 files changed, 335 insertions(+), 56 deletions(-)
data/launch/user | 10 ++
src/apps/installer/InstallerApp.cpp | 29 +++++
src/apps/installer/InstallerApp.h | 2 +
src/apps/installer/Jamfile | 12 +-
src/servers/launch/BaseJob.cpp | 11 +-
src/servers/launch/LaunchDaemon.cpp | 2 +
src/servers/launch/SettingsParser.cpp | 79 +++++++----
src/servers/launch/Utility.cpp | 56 +++++---
src/servers/launch/Utility.h | 1 +
src/servers/launch/Worker.cpp | 27 +++-
src/servers/launch/Worker.h | 2 +
src/tests/servers/launch/ConditionsTest.cpp | 6 +-
src/tests/servers/launch/Jamfile | 6 +-
src/tests/servers/launch/SettingsParserTest.cpp | 137 +++++++++++++++++++-
src/tests/servers/launch/SettingsParserTest.h | 11 ++

############################################################################

Commit: 963f548e6b3959c5fb9f2e7fcf0c4b58f45c6b0f
Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date: Fri Jul 10 14:12:43 2015 UTC

Installer: Unblock CD tray, and eject it, shutdown on quit.

* This was done in the Bootscript.cd before, but now the Installer
does it directly, but only in case the Deskbar is not running.

----------------------------------------------------------------------------

diff --git a/src/apps/installer/InstallerApp.cpp
b/src/apps/installer/InstallerApp.cpp
index 51ec1d2..b715805 100644
--- a/src/apps/installer/InstallerApp.cpp
+++ b/src/apps/installer/InstallerApp.cpp
@@ -1,4 +1,5 @@
/*
+ * Copyright 2015, Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
* Copyright 2009, Stephan Aßmus <superstippi@xxxxxx>
* Copyright 2005, Jérôme DUVAL.
* All rights reserved. Distributed under the terms of the MIT License.
@@ -6,10 +7,16 @@

#include "InstallerApp.h"

+#include <unistd.h>
+
#include <Alert.h>
+#include <Roster.h>
#include <TextView.h>

+#include <syscalls.h>
+
#include "tracker_private.h"
+#include "Utility.h"


static const uint32 kMsgAgree = 'agre';
@@ -108,3 +115,25 @@ InstallerApp::ReadyToRun()
new InstallerWindow();
#endif
}
+
+
+void
+InstallerApp::Quit()
+{
+ BApplication::Quit();
+
+ if (!be_roster->IsRunning(kDeskbarSignature)) {
+ // Synchronize disks, and reboot the system
+ sync();
+
+ if (Utility::IsReadOnlyVolume("/boot")) {
+ // Unblock CD tray, and eject the CD
+ Utility::BlockMedia("/boot", false);
+ Utility::EjectMedia("/boot");
+ }
+
+ // Quickly shutdown without possibly touching anything on disk
+ // (which we might just have ejected)
+ _kern_shutdown(false);
+ }
+}
diff --git a/src/apps/installer/InstallerApp.h
b/src/apps/installer/InstallerApp.h
index 49aa72a..4fb43aa 100644
--- a/src/apps/installer/InstallerApp.h
+++ b/src/apps/installer/InstallerApp.h
@@ -18,8 +18,10 @@ public:
InstallerApp();

virtual void MessageReceived(BMessage*
message);
+
virtual void AboutRequested();
virtual void ReadyToRun();
+ virtual void Quit();

private:
EULAWindow* fEULAWindow;
diff --git a/src/apps/installer/Jamfile b/src/apps/installer/Jamfile
index e3146bc..71e0230 100644
--- a/src/apps/installer/Jamfile
+++ b/src/apps/installer/Jamfile
@@ -1,7 +1,10 @@
SubDir HAIKU_TOP src apps installer ;

UsePrivateHeaders shared storage tracker ;
+UsePrivateSystemHeaders ;
+
SubDirHdrs [ FDirName $(HAIKU_TOP) src kits tracker ] ;
+SubDirHdrs [ FDirName $(HAIKU_TOP) src servers launch ] ;

Application Installer :
CopyEngine.cpp
@@ -14,11 +17,18 @@ Application Installer :
ProgressReporter.cpp
UnzipEngine.cpp
WorkerThread.cpp
- : be tracker translation libshared.a [ TargetLibstdc++ ]
+
+ # From launch_daemon
+ Utility.cpp
+
+ : be tracker translation libshared.a [ TargetLibstdc++ ]
localestub
: Installer.rdef
;

+SEARCH on <src!apps!installer>Utility.cpp = [
+ FDirName $(HAIKU_TOP) src servers launch ] ;
+
DoCatalogs Installer :
x-vnd.Haiku-Installer
:
diff --git a/src/servers/launch/Utility.cpp b/src/servers/launch/Utility.cpp
index 7d1c727..17f139f 100644
--- a/src/servers/launch/Utility.cpp
+++ b/src/servers/launch/Utility.cpp
@@ -17,6 +17,38 @@
#include <Volume.h>


+namespace {
+
+
+status_t
+IssueDeviceCommand(const char* path, int opcode, void* buffer,
+ size_t bufferSize)
+{
+ fs_info info;
+ if (fs_stat_dev(dev_for_path(path), &info) == B_OK) {
+ if (strcmp(info.fsh_name, "devfs") != 0)
+ path = info.device_name;
+ }
+
+ int device = open(path, O_RDONLY);
+ if (device < 0)
+ return device;
+
+ status_t status = B_OK;
+
+ if (ioctl(device, opcode, buffer, bufferSize) != 0) {
+ fprintf(stderr, "Failed to process %d on %s: %s\n", opcode,
path,
+ strerror(errno));
+ status = errno;
+ }
+ close(device);
+ return status;
+}
+
+
+} // private namespace
+
+
namespace Utility {


@@ -55,25 +87,15 @@ IsReadOnlyVolume(const char* path)
status_t
BlockMedia(const char* path, bool block)
{
- fs_info info;
- if (fs_stat_dev(dev_for_path(path), &info) == B_OK) {
- if (strcmp(info.fsh_name, "devfs") != 0)
- path = info.device_name;
- }
-
- int device = open(path, O_RDONLY);
- if (device < 0)
- return device;
+ return IssueDeviceCommand(path, B_SCSI_PREVENT_ALLOW, &block,
+ sizeof(block));
+}

- status_t status = B_OK;

- if (ioctl(device, B_SCSI_PREVENT_ALLOW, &block, sizeof(block)) != 0) {
- fprintf(stderr, "Failed to block media on %s: %s\n", path,
- strerror(errno));
- status = errno;
- }
- close(device);
- return status;
+status_t
+EjectMedia(const char* path)
+{
+ return IssueDeviceCommand(path, B_EJECT_DEVICE, NULL, 0);
}


diff --git a/src/servers/launch/Utility.h b/src/servers/launch/Utility.h
index 183b215..b5daf6d 100644
--- a/src/servers/launch/Utility.h
+++ b/src/servers/launch/Utility.h
@@ -14,6 +14,7 @@ namespace Utility {
bool IsReadOnlyVolume(const char* path);

status_t BlockMedia(const char* path, bool block);
+ status_t EjectMedia(const char* path);
}



############################################################################

Commit: 6e4aaae82c4f1c16ae1a3ca1910b15802fdfc238
Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date: Fri Jul 10 14:34:46 2015 UTC

launch_daemon: Fixed condition tests build.

* ConditionContext changed.

----------------------------------------------------------------------------

diff --git a/src/tests/servers/launch/ConditionsTest.cpp
b/src/tests/servers/launch/ConditionsTest.cpp
index d6ff329..ad9f6f9 100644
--- a/src/tests/servers/launch/ConditionsTest.cpp
+++ b/src/tests/servers/launch/ConditionsTest.cpp
@@ -22,6 +22,8 @@ class TestConditionContext : public ConditionContext {
public:
bool IsSafeMode() const
{
return false; }
+ bool BootVolumeIsReadOnly()
const
+ {
return false; }
};


@@ -45,7 +47,7 @@ ConditionsTest::TestSafemode()
CPPUNIT_ASSERT(!condition->Test(sConditionContext));
CPPUNIT_ASSERT(condition->IsConstant(sConditionContext));

- class SafemodeConditionContext : public ConditionContext {
+ class SafemodeConditionContext : public TestConditionContext {
public:
bool IsSafeMode() const
{
@@ -157,7 +159,7 @@ ConditionsTest::TestNot()
Condition* condition = _Condition("not safemode");
CPPUNIT_ASSERT(condition->Test(sConditionContext));

- class SafemodeConditionContext : public ConditionContext {
+ class SafemodeConditionContext : public TestConditionContext {
public:
bool IsSafeMode() const
{

############################################################################

Commit: 14ec22884cbd9d801f946a15aaa30e544a002c22
Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date: Fri Jul 10 14:58:28 2015 UTC

launch_daemon: Added events parsing.

* Including tests, also for the environment parsing.

----------------------------------------------------------------------------

diff --git a/src/servers/launch/SettingsParser.cpp
b/src/servers/launch/SettingsParser.cpp
index 8c81edf..fcc631e 100644
--- a/src/servers/launch/SettingsParser.cpp
+++ b/src/servers/launch/SettingsParser.cpp
@@ -9,7 +9,37 @@
#include <DriverSettingsMessageAdapter.h>


-class ConditionConverter : public DriverSettingsConverter {
+class AbstractArgsConverter : public DriverSettingsConverter {
+public:
+ status_t ConvertEmptyFromDriverSettings(
+ const driver_parameter& parameter, const char* name, uint32
type,
+ BMessage& target)
+ {
+ if (parameter.parameter_count != 0)
+ return B_OK;
+
+ BMessage message;
+ return target.AddMessage(name, &message);
+ }
+
+protected:
+ status_t AddSubMessage(const driver_parameter& parameter, int32 index,
+ BMessage& target)
+ {
+ const char* condition = parameter.values[index];
+ BMessage args;
+ for (index++; index < parameter.value_count; index++) {
+ status_t status = args.AddString("args",
+ parameter.values[index]);
+ if (status != B_OK)
+ return status;
+ }
+ return target.AddMessage(condition, &args);
+ }
+};
+
+
+class ConditionConverter : public AbstractArgsConverter {
public:
status_t ConvertFromDriverSettings(const driver_parameter& parameter,
const char* name, int32 index, uint32 type, BMessage& target)
@@ -29,7 +59,7 @@ public:
index++;
}

- status_t status = _AddSubMessage(parameter, index,
*add);
+ status_t status = AddSubMessage(parameter, index, *add);
if (status == B_OK && not)
status = target.AddMessage("not", &message);

@@ -39,37 +69,31 @@ public:
if (index != 0)
return B_OK;

- return _AddSubMessage(parameter, index, target);
+ return AddSubMessage(parameter, index, target);
}

message.AddString("args", parameter.values[index]);
return target.AddMessage(parameter.name, &message);
}
+};

- status_t ConvertEmptyFromDriverSettings(
- const driver_parameter& parameter, const char* name, uint32
type,
- BMessage& target)
- {
- if (parameter.parameter_count != 0)
- return B_OK;

+class EventConverter : public AbstractArgsConverter {
+public:
+ status_t ConvertFromDriverSettings(const driver_parameter& parameter,
+ const char* name, int32 index, uint32 type, BMessage& target)
+ {
BMessage message;
- return target.AddMessage(name, &message);
- }
+ if (strcmp(parameter.name, "on") == 0) {
+ // Parse values directly following "on"
+ if (index != 0)
+ return B_OK;

-private:
- status_t _AddSubMessage(const driver_parameter& parameter, int32 index,
- BMessage& target)
- {
- const char* condition = parameter.values[index];
- BMessage args;
- for (index++; index < parameter.value_count; index++) {
- status_t status = args.AddString("args",
- parameter.values[index]);
- if (status != B_OK)
- return status;
+ return AddSubMessage(parameter, index, target);
}
- return target.AddMessage(condition, &args);
+
+ message.AddString("args", parameter.values[index]);
+ return target.AddMessage(parameter.name, &message);
}
};

@@ -105,6 +129,13 @@ const static settings_template kConditionTemplate[] = {
{0, NULL, NULL}
};

+const static settings_template kEventTemplate[] = {
+ {B_STRING_TYPE, NULL, NULL, true, new EventConverter()},
+ {B_MESSAGE_TYPE, "and", kEventTemplate},
+ {B_MESSAGE_TYPE, "or", kEventTemplate},
+ {0, NULL, NULL}
+};
+
const static settings_template kPortTemplate[] = {
{B_STRING_TYPE, "name", NULL, true},
{B_INT32_TYPE, "capacity", NULL},
@@ -122,6 +153,7 @@ const static settings_template kJobTemplate[] = {
{B_STRING_TYPE, "requires", NULL},
{B_BOOL_TYPE, "legacy", NULL},
{B_MESSAGE_TYPE, "port", kPortTemplate},
+ {B_MESSAGE_TYPE, "on", kEventTemplate},
{B_MESSAGE_TYPE, "if", kConditionTemplate},
{B_BOOL_TYPE, "no_safemode", NULL},
{B_MESSAGE_TYPE, "env", kEnvTemplate},
@@ -131,6 +163,7 @@ const static settings_template kJobTemplate[] = {
const static settings_template kTargetTemplate[] = {
{B_STRING_TYPE, "name", NULL, true},
{B_BOOL_TYPE, "reset", NULL},
+ {B_MESSAGE_TYPE, "on", kEventTemplate},
{B_MESSAGE_TYPE, "if", kConditionTemplate},
{B_BOOL_TYPE, "no_safemode", NULL},
{B_MESSAGE_TYPE, "env", kEnvTemplate},
diff --git a/src/tests/servers/launch/Jamfile b/src/tests/servers/launch/Jamfile
index e0fb10e..f530bf6 100644
--- a/src/tests/servers/launch/Jamfile
+++ b/src/tests/servers/launch/Jamfile
@@ -10,10 +10,12 @@ UnitTestLib liblaunch_daemontest.so :
LaunchDaemonTestAddon.cpp

SettingsParserTest.cpp
- SettingsParser.cpp
-
ConditionsTest.cpp
+
+ # from the launch_daemon
+ SettingsParser.cpp
Conditions.cpp
+ Utility.cpp

: be libshared.a [ TargetLibstdc++ ] [ TargetLibsupc++ ]
;
diff --git a/src/tests/servers/launch/SettingsParserTest.cpp
b/src/tests/servers/launch/SettingsParserTest.cpp
index add04b9..aa34478 100644
--- a/src/tests/servers/launch/SettingsParserTest.cpp
+++ b/src/tests/servers/launch/SettingsParserTest.cpp
@@ -27,6 +27,9 @@ SettingsParserTest::~SettingsParserTest()
}


+// #pragma mark - conditions
+
+
void
SettingsParserTest::TestConditionsMultiLine()
{
@@ -178,6 +181,101 @@ SettingsParserTest::TestConditionsMultiLineNot()
}


+// #pragma mark - events
+
+
+void
+SettingsParserTest::TestEventsMultiLine()
+{
+ BMessage message;
+ CPPUNIT_ASSERT_EQUAL(B_OK, _ParseEvent("on {\n"
+ "\tfile_created one\n"
+ "\tdemand\n"
+ "}\n", message));
+ CPPUNIT_ASSERT_EQUAL(2, message.CountNames(B_ANY_TYPE));
+
+ BMessage subMessage;
+ CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("demand", &subMessage));
+ CPPUNIT_ASSERT(subMessage.IsEmpty());
+
+ CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("file_created",
+ &subMessage));
+ CPPUNIT_ASSERT_EQUAL(BString("one"),
+ BString(subMessage.GetString("args", 0, "-")));
+ CPPUNIT_ASSERT_EQUAL(1, subMessage.CountNames(B_ANY_TYPE));
+}
+
+
+void
+SettingsParserTest::TestEventsFlat()
+{
+ BMessage message;
+ CPPUNIT_ASSERT_EQUAL(B_OK, _ParseEvent("on demand\n", message));
+ CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
+
+ BMessage args;
+ CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("demand", &args));
+ CPPUNIT_ASSERT(args.IsEmpty());
+}
+
+
+void
+SettingsParserTest::TestEventsFlatWithArgs()
+{
+ BMessage message;
+ CPPUNIT_ASSERT_EQUAL(B_OK, _ParseEvent("on file_created one\n",
message));
+ CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
+
+ BMessage args;
+ CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("file_created", &args));
+ CPPUNIT_ASSERT_EQUAL(BString("one"),
+ BString(args.GetString("args", 0, "-")));
+ CPPUNIT_ASSERT_EQUAL(1, args.CountNames(B_ANY_TYPE));
+}
+
+
+// #pragma mark - environment
+
+
+void
+SettingsParserTest::TestEnvironmentMultiLine()
+{
+ BMessage message;
+ CPPUNIT_ASSERT_EQUAL(B_OK, _ParseName("env", "env {\n"
+ "from_script SetupEnvironment\n"
+ "TEST well, yes\n"
+ "}\n", message));
+ CPPUNIT_ASSERT_EQUAL(2, message.CountNames(B_ANY_TYPE));
+
+ CPPUNIT_ASSERT_EQUAL(BString("SetupEnvironment"),
+ BString(message.GetString("from_script", "-")));
+ CPPUNIT_ASSERT_EQUAL(1, _ArrayCount(message, "from_script"));
+
+ CPPUNIT_ASSERT_EQUAL(BString("well,"),
+ BString(message.GetString("TEST", 0, "-")));
+ CPPUNIT_ASSERT_EQUAL(BString("yes"),
+ BString(message.GetString("TEST", 1, "-")));
+ CPPUNIT_ASSERT_EQUAL(2, _ArrayCount(message, "TEST"));
+}
+
+
+void
+SettingsParserTest::TestEnvironmentFlat()
+{
+ BMessage message;
+ CPPUNIT_ASSERT_EQUAL(B_OK, _ParseName("env", "env SetupEnvironment\n",
+ message));
+ CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
+
+ CPPUNIT_ASSERT_EQUAL(BString("SetupEnvironment"),
+ BString(message.GetString("from_script", "-")));
+ CPPUNIT_ASSERT_EQUAL(1, _ArrayCount(message, "from_script"));
+}
+
+
+// #pragma mark - run
+
+
void
SettingsParserTest::TestRunFlat()
{
@@ -288,6 +386,9 @@ SettingsParserTest::TestRunIfThenElseMultiLine()
}


+// #pragma mark -
+
+
/*static*/ void
SettingsParserTest::AddTests(BTestSuite& parent)
{
@@ -319,6 +420,25 @@ SettingsParserTest::AddTests(BTestSuite& parent)
"SettingsParserTest::TestConditionsMultiLineNot",
&SettingsParserTest::TestConditionsMultiLineNot));

+ // Events
+ suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
+ "SettingsParserTest::TestEventsMultiLine",
+ &SettingsParserTest::TestEventsMultiLine));
+ suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
+ "SettingsParserTest::TestEventsFlat",
+ &SettingsParserTest::TestEventsFlat));
+ suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
+ "SettingsParserTest::TestEventsFlatWithArgs",
+ &SettingsParserTest::TestEventsFlatWithArgs));
+
+ // Environment
+ suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
+ "SettingsParserTest::TestEnvironmentMultiLine",
+ &SettingsParserTest::TestEnvironmentMultiLine));
+ suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
+ "SettingsParserTest::TestEnvironmentFlat",
+ &SettingsParserTest::TestEnvironmentFlat));
+
// Run
suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
"SettingsParserTest::TestRunFlat",
@@ -340,6 +460,21 @@ SettingsParserTest::AddTests(BTestSuite& parent)
status_t
SettingsParserTest::_ParseCondition(const char* text, BMessage& message)
{
+ return _ParseName("if", text, message);
+}
+
+
+status_t
+SettingsParserTest::_ParseEvent(const char* text, BMessage& message)
+{
+ return _ParseName("on", text, message);
+}
+
+
+status_t
+SettingsParserTest::_ParseName(const char* name, const char* text,
+ BMessage& message)
+{
SettingsParser parser;
BString input("job A {\n");
input << text << "\n}\n";
@@ -357,7 +492,7 @@ SettingsParserTest::_ParseCondition(const char* text,
BMessage& message)
CPPUNIT_ASSERT_EQUAL(2, job.CountNames(B_ANY_TYPE));
CPPUNIT_ASSERT_EQUAL(BString("A"), BString(job.GetString("name")));

- return job.FindMessage("if", &message);
+ return job.FindMessage(name, &message);
}


diff --git a/src/tests/servers/launch/SettingsParserTest.h
b/src/tests/servers/launch/SettingsParserTest.h
index d9ffa39..634c07a 100644
--- a/src/tests/servers/launch/SettingsParserTest.h
+++ b/src/tests/servers/launch/SettingsParserTest.h
@@ -26,6 +26,13 @@ public:
void
TestConditionsMultiLineFlatNotWithArgs();
void
TestConditionsMultiLineNot();

+ void TestEventsMultiLine();
+ void TestEventsFlat();
+ void
TestEventsFlatWithArgs();
+
+ void
TestEnvironmentMultiLine();
+ void TestEnvironmentFlat();
+
void TestRunFlat();
void TestRunMultiLine();
void TestRunIfThenElseFlat();
@@ -36,6 +43,10 @@ public:
private:
status_t _ParseCondition(const
char* text,

BMessage& message);
+ status_t _ParseEvent(const char*
text,
+
BMessage& message);
+ status_t _ParseName(const char*
name, const char* text,
+
BMessage& message);
int32 _ArrayCount(BMessage&
message,
const
char* name);
};

############################################################################

Commit: 31e1780963abbc130f1421c85301d982006983b5
Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date: Fri Jul 10 15:05:17 2015 UTC

launch_daemon: Fixed a race condition in Worker startup.

* When the thread is started during the construction of the base
class, the virtual method table may still point to the methods
of the base class when the thread actually starts to run.
* This caused the main worker to have a timeout, which could
eventually be reached which in turn caused all job processing
to stop.
* That's what you get when you do Java all day; whoever designed
C++ should be slapped (I'm talking to you, Bjarne).

----------------------------------------------------------------------------

diff --git a/src/servers/launch/LaunchDaemon.cpp
b/src/servers/launch/LaunchDaemon.cpp
index 9d56171..63a6245 100644
--- a/src/servers/launch/LaunchDaemon.cpp
+++ b/src/servers/launch/LaunchDaemon.cpp
@@ -164,6 +164,8 @@ LaunchDaemon::LaunchDaemon(bool userMode, status_t& error)
fUserMode(userMode)
{
fMainWorker = new MainWorker(fJobQueue);
+ fMainWorker->Init();
+
if (fInitTarget != NULL)
_AddTarget(fInitTarget);

diff --git a/src/servers/launch/Worker.cpp b/src/servers/launch/Worker.cpp
index d435a17..5e33760 100644
--- a/src/servers/launch/Worker.cpp
+++ b/src/servers/launch/Worker.cpp
@@ -15,12 +15,9 @@ static int32 sWorkerCount;

Worker::Worker(JobQueue& queue)
:
+ fThread(-1),
fJobQueue(queue)
{
- fThread = spawn_thread(&Worker::_Process, "worker", B_NORMAL_PRIORITY,
- this);
- if (fThread >= 0 && resume_thread(fThread) == B_OK)
- atomic_add(&sWorkerCount, 1);
}


@@ -30,6 +27,22 @@ Worker::~Worker()


status_t
+Worker::Init()
+{
+ fThread = spawn_thread(&Worker::_Process, "worker", B_NORMAL_PRIORITY,
+ this);
+ if (fThread < 0)
+ return fThread;
+
+ status_t status = resume_thread(fThread);
+ if (status == B_OK)
+ atomic_add(&sWorkerCount, 1);
+
+ return status;
+}
+
+
+status_t
Worker::Process()
{
while (true) {
@@ -103,8 +116,10 @@ MainWorker::Run(BJob* job)
if (jobCount > INT_MAX)
jobCount = INT_MAX;

- if ((int32)jobCount > count && count < fCPUCount)
- new Worker(fJobQueue);
+ if ((int32)jobCount > count && count < fCPUCount) {
+ Worker* worker = new Worker(fJobQueue);
+ worker->Init();
+ }

return Worker::Run(job);
}
diff --git a/src/servers/launch/Worker.h b/src/servers/launch/Worker.h
index bcc3e28..beb333d 100644
--- a/src/servers/launch/Worker.h
+++ b/src/servers/launch/Worker.h
@@ -19,6 +19,8 @@ public:

Worker(JobQueue& queue);
virtual ~Worker();

+ status_t Init();
+
protected:
virtual status_t Process();
virtual bigtime_t Timeout() const;

############################################################################

Commit: 9e93bb57f3d1c5db9e3b8e4db00617e094cf0e90
Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date: Fri Jul 10 15:08:22 2015 UTC

launch_daemon: Improved error reporting, minor cleanup.

----------------------------------------------------------------------------

diff --git a/src/servers/launch/BaseJob.cpp b/src/servers/launch/BaseJob.cpp
index a98ba07..61ed7a6 100644
--- a/src/servers/launch/BaseJob.cpp
+++ b/src/servers/launch/BaseJob.cpp
@@ -6,7 +6,9 @@

#include "BaseJob.h"

+#include <errno.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>

#include <Message.h>
@@ -103,10 +105,10 @@ BaseJob::SetEnvironment(const BMessage& message)
for (int32 index = 0; message.GetInfo(B_STRING_TYPE, index, &name,
&type,
&count) == B_OK; index++) {
if (strcmp(name, "from_script") == 0) {
- const char* fromFile;
- for (int32 fileIndex = 0; message.FindString(name,
fileIndex,
- &fromFile) == B_OK; fileIndex++) {
- fSourceFiles.Add(fromFile);
+ const char* fromScript;
+ for (int32 scriptIndex = 0; message.FindString(name,
scriptIndex,
+ &fromScript) == B_OK; scriptIndex++) {
+ fSourceFiles.Add(fromScript);
}
continue;
}
@@ -166,6 +168,7 @@ BaseJob::_GetSourceFileEnvironment(const char* script,
BStringList& environment)
pid_t child = fork();
if (child < 0) {
// TODO: log error
+ debug_printf("could not fork: %s\n", strerror(errno));
} else if (child == 0) {
// We're the child, redirect stdout
close(STDOUT_FILENO);

############################################################################

Commit: 955efcfea94105eaaed1b1d948446fdd31bff37d
Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date: Fri Jul 10 15:08:50 2015 UTC

Create installer link in live mode, check existence.

* FirstBootPrompt as well as the Installer do not exist on the
minimum image, so take this into account when making the startup
target decisions.

----------------------------------------------------------------------------

diff --git a/data/launch/user b/data/launch/user
index b552fd5..20950ac 100644
--- a/data/launch/user
+++ b/data/launch/user
@@ -10,6 +10,15 @@ target desktop {
launch /system/Deskbar
legacy
}
+
+ job create-installer-link {
+ # When run from a read-only medium a.k.a. live desktop
+ if {
+ read_only
+ file_exists /boot/system/apps/Installer
+ }
+ launch /bin/ln -sf /boot/system/apps/Installer
/boot/home/Desktop/Installer
+ }
}

target first_boot {
@@ -22,6 +31,7 @@ target installer {

run {
if {
+ file_exists /system/bin/FirstBootPrompt
or {
not file_exists /boot/home/config/settings/Locale\
settings
read_only


Other related posts:

  • » [haiku-commits] BRANCH axeld-github.launch_daemon [955efcfea941] src/tests/servers/launch src/servers/launch src/apps/installer data/launch - axeld-github . launch_daemon