[haiku-commits] BRANCH axeld-github.launch_daemon [cc66427371e5] in src: servers/launch . kits/app

  • From: axeld-github.launch_daemon <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 16 Jun 2015 14:31:57 +0200 (CEST)

added 4 changesets to branch 'refs/remotes/axeld-github/launch_daemon'
old head: 2651d9c50aebe4975c9a7bc2c6bd807ebef52575
new head: cc66427371e5f6791c18198cb545579d7b148710
overview: https://github.com/axeld/haiku/compare/2651d9c50aeb...cc66427371e5

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

3ece81c5c908: JobQueue::AddJob() returns error on lock failure.

* If the lock could not be obtained, it will now return B_ERROR
instead of B_OK.

668ab1589517: Sudoku: Don't switch workspace for progress window.

7cc7807d92ea: launch_daemon: Improved target support.

* You can now put jobs/services into a target.
* Instead of having Login started as part of the normal boot process,
it's now in the "login" target.
* The app_server now launches the login target when a login becomes
available (ie. during startup, but that could be improved later on).

cc66427371e5: launch_daemon: Moved Job+Target into separate files.

[ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ]

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

14 files changed, 813 insertions(+), 464 deletions(-)
data/launch/system | 8 +-
headers/private/app/LaunchDaemonDefs.h | 5 +-
headers/private/app/LaunchRoster.h | 3 +
headers/private/app/LaunchRosterPrivate.h | 2 +-
src/apps/sudoku/ProgressWindow.cpp | 5 +-
src/kits/app/LaunchRoster.cpp | 35 +-
src/kits/support/JobQueue.cpp | 27 +-
src/servers/app/AppServer.cpp | 15 +-
src/servers/launch/Jamfile | 2 +
src/servers/launch/Job.cpp | 407 ++++++++++++++++++
src/servers/launch/Job.h | 102 +++++
src/servers/launch/LaunchDaemon.cpp | 597 +++++++-------------------
src/servers/launch/Target.cpp | 35 ++
src/servers/launch/Target.h | 34 ++

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

Commit: 3ece81c5c9087457c8d218b58d16eb1b8de53fc8
Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date: Mon Jun 15 16:47:21 2015 UTC

JobQueue::AddJob() returns error on lock failure.

* If the lock could not be obtained, it will now return B_ERROR
instead of B_OK.

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

diff --git a/src/kits/support/JobQueue.cpp b/src/kits/support/JobQueue.cpp
index 0246c75..9749039 100644
--- a/src/kits/support/JobQueue.cpp
+++ b/src/kits/support/JobQueue.cpp
@@ -84,20 +84,21 @@ JobQueue::AddJob(BJob* job)
return B_NO_INIT;

BAutolock lock(&fLock);
- if (lock.IsLocked()) {
- try {
- if (!fQueuedJobs->insert(job).second)
- return B_NAME_IN_USE;
- } catch (const std::bad_alloc& e) {
- return B_NO_MEMORY;
- } catch (...) {
- return B_ERROR;
- }
- BJob::Private(*job).SetTicketNumber(fNextTicketNumber++);
- job->AddStateListener(this);
- if (job->IsRunnable())
- release_sem(fHaveRunnableJobSem);
+ if (!lock.IsLocked())
+ return B_ERROR;
+
+ try {
+ if (!fQueuedJobs->insert(job).second)
+ return B_NAME_IN_USE;
+ } catch (const std::bad_alloc& e) {
+ return B_NO_MEMORY;
+ } catch (...) {
+ return B_ERROR;
}
+ BJob::Private(*job).SetTicketNumber(fNextTicketNumber++);
+ job->AddStateListener(this);
+ if (job->IsRunnable())
+ release_sem(fHaveRunnableJobSem);

return B_OK;
}

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

Commit: 668ab1589517e9c0137d0a273234923717396584
Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date: Mon Jun 15 16:48:33 2015 UTC

Sudoku: Don't switch workspace for progress window.

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

diff --git a/src/apps/sudoku/ProgressWindow.cpp
b/src/apps/sudoku/ProgressWindow.cpp
index c8d7251..8bd76ed 100644
--- a/src/apps/sudoku/ProgressWindow.cpp
+++ b/src/apps/sudoku/ProgressWindow.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2011, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2007-2015, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
* Distributed under the terms of the MIT License.
*/

@@ -27,7 +27,8 @@ ProgressWindow::ProgressWindow(BWindow* referenceWindow,
BMessage* abortMessage)
: BWindow(BRect(0, 0, 250, 100), B_TRANSLATE("Progress monitor"),
B_MODAL_WINDOW_LOOK, B_FLOATING_APP_WINDOW_FEEL,
- B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS),
+ B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS
+ | B_NO_WORKSPACE_ACTIVATION),
fRunner(NULL)
{
BRect rect = Bounds();

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

Commit: 7cc7807d92eadfc8936e449cf8cc23eda3989b76
Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date: Mon Jun 15 16:50:04 2015 UTC

launch_daemon: Improved target support.

* You can now put jobs/services into a target.
* Instead of having Login started as part of the normal boot process,
it's now in the "login" target.
* The app_server now launches the login target when a login becomes
available (ie. during startup, but that could be improved later on).

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

diff --git a/data/launch/system b/data/launch/system
index e95676d..9bf13f8 100644
--- a/data/launch/system
+++ b/data/launch/system
@@ -71,7 +71,9 @@ service x-vnd.Haiku-power_daemon {
legacy
}

-job x-vnd.Haiku-Login {
- launch /system/apps/Login
- legacy
+target login {
+ job x-vnd.Haiku-Login {
+ launch /system/apps/Login
+ legacy
+ }
}
diff --git a/headers/private/app/LaunchDaemonDefs.h
b/headers/private/app/LaunchDaemonDefs.h
index 8f7cab4..ec08f10 100644
--- a/headers/private/app/LaunchDaemonDefs.h
+++ b/headers/private/app/LaunchDaemonDefs.h
@@ -19,14 +19,15 @@
namespace BPrivate {

#define kLaunchDaemonSignature "application/x-vnd.Haiku-launch_daemon"
-#define B_LAUNCH_DAEMON_PORT_NAME "system:launch_daemon"
+#define B_LAUNCH_DAEMON_PORT_NAME "system:launch_daemon"


// message constants
enum {
B_GET_LAUNCH_DATA = 'lnda',
+ B_LAUNCH_TARGET = 'lntg',
B_LAUNCH_SESSION = 'lnse',
- B_REGISTER_LAUNCH_SESSION = 'lnrs',
+ B_REGISTER_SESSION_DAEMON = 'lnrs',
};


diff --git a/headers/private/app/LaunchRoster.h
b/headers/private/app/LaunchRoster.h
index 7e3320e..5a85161 100644
--- a/headers/private/app/LaunchRoster.h
+++ b/headers/private/app/LaunchRoster.h
@@ -22,6 +22,9 @@ public:
port_id GetPort(const char*
signature,
const
char* name);

+ status_t Target(const char*
name, BMessage& data,
+ const
char* baseName = NULL);
+
status_t StartSession(const
char* login,
const
char* password);

diff --git a/headers/private/app/LaunchRosterPrivate.h
b/headers/private/app/LaunchRosterPrivate.h
index 9dce48a..613efcb 100644
--- a/headers/private/app/LaunchRosterPrivate.h
+++ b/headers/private/app/LaunchRosterPrivate.h
@@ -14,7 +14,7 @@ public:

Private(BLaunchRoster* roster);

Private(BLaunchRoster& roster);

- status_t RegisterSession(const
BMessenger& target);
+ status_t
RegisterSessionDaemon(const BMessenger& daemon);

private:
BLaunchRoster* fRoster;
diff --git a/src/kits/app/LaunchRoster.cpp b/src/kits/app/LaunchRoster.cpp
index 4fd0ce7..5d4ea84 100644
--- a/src/kits/app/LaunchRoster.cpp
+++ b/src/kits/app/LaunchRoster.cpp
@@ -39,12 +39,12 @@ BLaunchRoster::Private::Private(BLaunchRoster& roster)


status_t
-BLaunchRoster::Private::RegisterSession(const BMessenger& target)
+BLaunchRoster::Private::RegisterSessionDaemon(const BMessenger& daemon)
{
- BMessage request(B_REGISTER_LAUNCH_SESSION);
+ BMessage request(B_REGISTER_SESSION_DAEMON);
status_t status = request.AddInt32("user", getuid());
if (status == B_OK)
- status = request.AddMessenger("target", target);
+ status = request.AddMessenger("daemon", daemon);
if (status != B_OK)
return status;

@@ -146,6 +146,35 @@ BLaunchRoster::GetPort(const char* signature, const char*
name)


status_t
+BLaunchRoster::Target(const char* name, BMessage& data, const char* baseName)
+{
+ if (name == NULL)
+ return B_BAD_VALUE;
+
+ BMessage request(B_LAUNCH_TARGET);
+ status_t status = request.AddInt32("user", getuid());
+ if (status == B_OK)
+ status = request.AddString("target", name);
+ if (status == B_OK && !data.IsEmpty())
+ status = request.AddMessage("data", &data);
+ if (status == B_OK && baseName != NULL)
+ status = request.AddString("base target", baseName);
+ if (status != B_OK)
+ return status;
+
+ // send the request
+ BMessage result;
+ status = fMessenger.SendMessage(&request, &result);
+
+ // evaluate the reply
+ if (status == B_OK)
+ status = result.what;
+
+ return status;
+}
+
+
+status_t
BLaunchRoster::StartSession(const char* login, const char* password)
{
if (login == NULL || password == NULL)
diff --git a/src/servers/app/AppServer.cpp b/src/servers/app/AppServer.cpp
index 004b7f4..710d61c 100644
--- a/src/servers/app/AppServer.cpp
+++ b/src/servers/app/AppServer.cpp
@@ -12,6 +12,11 @@

#include "AppServer.h"

+#include <syslog.h>
+
+#include <LaunchRoster.h>
+#include <PortLink.h>
+
#include "BitmapManager.h"
#include "Desktop.h"
#include "FontManager.h"
@@ -19,10 +24,6 @@
#include "ScreenManager.h"
#include "ServerProtocol.h"

-#include <PortLink.h>
-
-#include <syslog.h>
-

//#define DEBUG_SERVER
#ifdef DEBUG_SERVER
@@ -66,6 +67,12 @@ AppServer::AppServer(status_t* status)

// Create the bitmap allocator. Object declared in BitmapManager.cpp
gBitmapManager = new BitmapManager();
+
+ // TODO: check the attached displays, and launch login session for them
+ BMessage data;
+ data.AddString("name", "app_server");
+ data.AddInt32("session", 0);
+ BLaunchRoster().Target("login", data);
}


diff --git a/src/servers/launch/LaunchDaemon.cpp
b/src/servers/launch/LaunchDaemon.cpp
index c9bf587..ef57f9e 100644
--- a/src/servers/launch/LaunchDaemon.cpp
+++ b/src/servers/launch/LaunchDaemon.cpp
@@ -60,7 +60,16 @@ const static settings_template kJobTemplate[] = {
{0, NULL, NULL}
};

+const static settings_template kTargetTemplate[] = {
+ {B_STRING_TYPE, "name", NULL, true},
+ {B_BOOL_TYPE, "reset", NULL},
+ {B_MESSAGE_TYPE, "job", kJobTemplate},
+ {B_MESSAGE_TYPE, "service", kJobTemplate},
+ {0, NULL, NULL}
+};
+
const static settings_template kSettingsTemplate[] = {
+ {B_MESSAGE_TYPE, "target", kTargetTemplate},
{B_MESSAGE_TYPE, "job", kJobTemplate},
{B_MESSAGE_TYPE, "service", kJobTemplate},
{0, NULL, NULL}
@@ -76,12 +85,12 @@ public:

uid_t User() const
{
return fUser; }
- const BMessenger& Target() const
- {
return fTarget; }
+ const BMessenger& Daemon() const
+ {
return fDaemon; }

private:
uid_t fUser;
- BMessenger fTarget;
+ BMessenger fDaemon;
};


@@ -89,17 +98,27 @@ class Target : public BJob {
public:
Target(const
char* name);

+ const char* Name() const;
+
+ status_t AddData(const char*
name, BMessage& data);
+ const BMessage& Data() const
+ {
return fData; }
+
protected:
virtual status_t Execute();
+
+private:
+ BMessage fData;
};


-class JobFinder;
+class Finder;


class Job : public BJob {
public:
Job(const char*
name);
+ Job(const Job&
other);
virtual ~Job();

const char* Name() const;
@@ -122,11 +141,14 @@ public:
BStringList& Arguments();
void AddArgument(const char*
argument);

+ ::Target* Target() const;
+ void SetTarget(::Target*
target);
+
const BStringList& Requirements() const;
BStringList& Requirements();
void AddRequirement(const
char* requirement);

- status_t Init(Target* target,
const JobFinder& jobs,
+ status_t Init(const Finder& jobs,

std::set<BString>& dependencies);
status_t InitCheck() const;

@@ -142,7 +164,11 @@ protected:
virtual status_t Execute();

private:
- BString fName;
+ Job& operator=(const Job&
other);
+ void _DeletePorts();
+ status_t _AddRequirement(BJob*
dependency);
+
+private:
BStringList fArguments;
BStringList fRequirements;
bool fEnabled;
@@ -152,25 +178,29 @@ private:
PortMap fPortMap;
status_t fInitStatus;
team_id fTeam;
+ ::Target* fTarget;
};


-class JobFinder {
+class Finder {
public:
virtual Job* FindJob(const char* name) const
= 0;
+ virtual Target* FindTarget(const char* name)
const = 0;
};


typedef std::map<BString, Job*> JobMap;
typedef std::map<uid_t, Session*> SessionMap;
+typedef std::map<BString, Target*> TargetMap;


-class LaunchDaemon : public BServer, public JobFinder {
+class LaunchDaemon : public BServer, public Finder {
public:

LaunchDaemon(bool userMode, status_t& error);
virtual ~LaunchDaemon();

virtual Job* FindJob(const char* name) const;
+ virtual Target* FindTarget(const char* name)
const;
Session* FindSession(uid_t user)
const;

virtual void ReadyToRun();
@@ -185,10 +215,13 @@ private:
BEntry&
directory);
status_t _ReadFile(const char*
context, BEntry& entry);

- void _AddJob(bool service,
BMessage& message);
- void _InitJobs(Target*
target);
- void _LaunchJobs();
+ void _AddJobs(Target*
target, BMessage& message);
+ void _AddJob(Target* target,
bool service,
+
BMessage& message);
+ void _InitJobs();
+ void _LaunchJobs(Target*
target);
void _AddLaunchJob(Job* job);
+ void _AddTarget(Target*
target);

status_t _StartSession(const
char* login,
const
char* password);
@@ -202,6 +235,7 @@ private:

private:
JobMap fJobs;
+ TargetMap fTargets;
JobQueue fJobQueue;
SessionMap fSessions;
MainWorker* fMainWorker;
@@ -233,19 +267,44 @@ Job::Job(const char* name)
fCreateDefaultPort(false),
fLaunchInSafeMode(true),
fInitStatus(B_NO_INIT),
- fTeam(-1)
+ fTeam(-1),
+ fTarget(NULL)
{
}


-Job::~Job()
+Job::Job(const Job& other)
+ :
+ BJob(other.Name()),
+ fEnabled(other.IsEnabled()),
+ fService(other.IsService()),
+ fCreateDefaultPort(other.CreateDefaultPort()),
+ fLaunchInSafeMode(other.LaunchInSafeMode()),
+ fInitStatus(B_NO_INIT),
+ fTeam(-1),
+ fTarget(other.Target())
{
- PortMap::const_iterator iterator = Ports().begin();
- for (; iterator != Ports().end(); iterator++) {
- port_id port = iterator->second.GetInt32("port", -1);
- if (port >= 0)
- delete_port(port);
+ for (int32 i = 0; i < other.Arguments().CountStrings(); i++)
+ AddArgument(other.Arguments().StringAt(i));
+
+ for (int32 i = 0; i < other.Requirements().CountStrings(); i++)
+ AddRequirement(other.Requirements().StringAt(i));
+
+ PortMap::const_iterator constIterator = other.Ports().begin();
+ for (; constIterator != other.Ports().end(); constIterator++) {
+ fPortMap.insert(
+ std::make_pair(constIterator->first,
constIterator->second));
}
+
+ PortMap::iterator iterator = fPortMap.begin();
+ for (; iterator != fPortMap.end(); iterator++)
+ iterator->second.RemoveData("port");
+}
+
+
+Job::~Job()
+{
+ _DeletePorts();
}


@@ -341,6 +400,20 @@ Job::AddArgument(const char* argument)
}


+::Target*
+Job::Target() const
+{
+ return fTarget;
+}
+
+
+void
+Job::SetTarget(::Target* target)
+{
+ fTarget = target;
+}
+
+
const BStringList&
Job::Requirements() const
{
@@ -363,8 +436,7 @@ Job::AddRequirement(const char* requirement)


status_t
-Job::Init(Target* target, const JobFinder& jobs,
- std::set<BString>& dependencies)
+Job::Init(const Finder& finder, std::set<BString>& dependencies)
{
// Only initialize the jobs once
if (fInitStatus != B_NO_INIT)
@@ -372,8 +444,8 @@ Job::Init(Target* target, const JobFinder& jobs,

fInitStatus = B_OK;

- if (target != NULL && target->State() < B_JOB_STATE_SUCCEEDED)
- AddDependency(target);
+ if (fTarget != NULL)
+ fTarget->AddDependency(this);

// Check dependencies

@@ -386,21 +458,29 @@ Job::Init(Target* target, const JobFinder& jobs,
}
dependencies.insert(requires);

- Job* dependency = jobs.FindJob(requires);
+ Job* dependency = finder.FindJob(requires);
if (dependency != NULL) {
std::set<BString> subDependencies = dependencies;

- fInitStatus = dependency->Init(target, jobs,
subDependencies);
+ fInitStatus = dependency->Init(finder, subDependencies);
if (fInitStatus != B_OK) {
// TODO: log error
return fInitStatus;
}

- AddDependency(dependency);
+ fInitStatus = _AddRequirement(dependency);
} else {
- // Could not find dependency
+ ::Target* target = finder.FindTarget(requires);
+ if (target != NULL)
+ fInitStatus = _AddRequirement(dependency);
+ else {
+ // Could not find dependency
+ fInitStatus = B_NAME_NOT_FOUND;
+ }
+ }
+ if (fInitStatus != B_OK) {
// TODO: log error
- return fInitStatus = B_NAME_NOT_FOUND;
+ return fInitStatus;
}
}

@@ -487,7 +567,7 @@ Job::Launch()
// We cannot use the BRoster here as it tries to pre-register
// the application.
BString signature("application/");
- signature << fName;
+ signature << Name();
return B_NOT_SUPPORTED;
//return be_roster->Launch(signature.String(), (BMessage*)NULL,
&fTeam);
}
@@ -534,13 +614,52 @@ Job::Execute()
}


+void
+Job::_DeletePorts()
+{
+ PortMap::const_iterator iterator = Ports().begin();
+ for (; iterator != Ports().end(); iterator++) {
+ port_id port = iterator->second.GetInt32("port", -1);
+ if (port >= 0)
+ delete_port(port);
+ }
+}
+
+
+status_t
+Job::_AddRequirement(BJob* dependency)
+{
+ if (dependency == NULL)
+ return B_OK;
+
+ switch (dependency->State()) {
+ case B_JOB_STATE_WAITING_TO_RUN:
+ case B_JOB_STATE_STARTED:
+ case B_JOB_STATE_IN_PROGRESS:
+ AddDependency(dependency);
+ break;
+
+ case B_JOB_STATE_SUCCEEDED:
+ // Just queue it without any dependencies
+ break;
+
+ case B_JOB_STATE_FAILED:
+ case B_JOB_STATE_ABORTED:
+ // TODO: return appropriate error
+ return B_BAD_VALUE;
+ }
+
+ return B_OK;
+}
+
+
// #pragma mark -


-Session::Session(uid_t user, const BMessenger& target)
+Session::Session(uid_t user, const BMessenger& daemon)
:
fUser(user),
- fTarget(target)
+ fDaemon(daemon)
{
}

@@ -555,6 +674,20 @@ Target::Target(const char* name)
}


+const char*
+Target::Name() const
+{
+ return Title().String();
+}
+
+
+status_t
+Target::AddData(const char* name, BMessage& data)
+{
+ return fData.AddMessage(name, &data);
+}
+
+
status_t
Target::Execute()
{
@@ -574,6 +707,8 @@ LaunchDaemon::LaunchDaemon(bool userMode, status_t& error)
fUserMode(userMode)
{
fMainWorker = new MainWorker(fJobQueue);
+ if (fInitTarget != NULL)
+ _AddTarget(fInitTarget);
}


@@ -596,6 +731,20 @@ LaunchDaemon::FindJob(const char* name) const
}


+Target*
+LaunchDaemon::FindTarget(const char* name) const
+{
+ if (name == NULL)
+ return NULL;
+
+ TargetMap::const_iterator found =
fTargets.find(BString(name).ToLower());
+ if (found != fTargets.end())
+ return found->second;
+
+ return NULL;
+}
+
+
Session*
LaunchDaemon::FindSession(uid_t user) const
{
@@ -614,7 +763,7 @@ LaunchDaemon::ReadyToRun()
_SetupEnvironment();
if (fUserMode) {
BLaunchRoster roster;
- BLaunchRoster::Private(roster).RegisterSession(this);
+ BLaunchRoster::Private(roster).RegisterSessionDaemon(this);
} else
_InitSystem();

@@ -627,8 +776,8 @@ LaunchDaemon::ReadyToRun()
fUserMode ? B_FIND_PATHS_USER_ONLY : B_FIND_PATHS_SYSTEM_ONLY,
paths);
_ReadPaths(paths);

- _InitJobs(fUserMode ? NULL : fInitTarget);
- _LaunchJobs();
+ _InitJobs();
+ _LaunchJobs(NULL);
}


@@ -648,7 +797,7 @@ LaunchDaemon::MessageReceived(BMessage* message)
Session* session = FindSession(user);
if (session != NULL) {
// Forward request to user launch_daemon
- if
(session->Target().SendMessage(message) == B_OK)
+ if
(session->Daemon().SendMessage(message) == B_OK)
break;
}
reply.what = B_NAME_NOT_FOUND;
@@ -676,6 +825,57 @@ LaunchDaemon::MessageReceived(BMessage* message)
break;
}

+ case B_LAUNCH_TARGET:
+ {
+ uid_t user = _GetUserID(message);
+ if (user < 0)
+ break;
+
+ const char* name = message->GetString("target");
+ const char* baseName = message->GetString("base
target");
+
+ Target* target = FindTarget(name);
+ if (target == NULL) {
+ Target* baseTarget = FindTarget(baseName);
+ if (baseTarget != NULL) {
+ target = new Target(name);
+
+ // Copy all jobs with the base target
into the new target
+ for (JobMap::iterator iterator =
fJobs.begin();
+ iterator !=
fJobs.end();) {
+ Job* job = iterator->second;
+ iterator++;
+
+ if (job->Target() ==
baseTarget) {
+ Job* copy = new
Job(*job);
+ copy->SetTarget(target);
+
+
fJobs.insert(std::make_pair(copy->Name(), copy));
+ }
+ }
+ }
+ }
+ if (target == NULL) {
+ Session* session = FindSession(user);
+ if (session != NULL) {
+ // Forward request to user launch_daemon
+ if
(session->Daemon().SendMessage(message) == B_OK)
+ break;
+ }
+
+ BMessage reply(B_NAME_NOT_FOUND);
+ message->SendReply(&reply);
+ break;
+ }
+
+ BMessage data;
+ if (message->FindMessage("data", &data) == B_OK)
+ target->AddData(data.GetString("name"), data);
+
+ _LaunchJobs(target);
+ break;
+ }
+
case B_LAUNCH_SESSION:
{
uid_t user = _GetUserID(message);
@@ -699,7 +899,7 @@ LaunchDaemon::MessageReceived(BMessage* message)
break;
}

- case B_REGISTER_LAUNCH_SESSION:
+ case B_REGISTER_SESSION_DAEMON:
{
uid_t user = _GetUserID(message);
if (user < 0)
@@ -792,16 +992,37 @@ LaunchDaemon::_ReadFile(const char* context, BEntry&
entry)
status = adapter.ConvertFromDriverSettings(path.Path(),
kSettingsTemplate,
message);
if (status == B_OK) {
- message.PrintToStream();
- BMessage job;
- for (int32 index = 0; message.FindMessage("service", index,
- &job) == B_OK; index++) {
- _AddJob(true, job);
- }
+ _AddJobs(NULL, message);

- for (int32 index = 0; message.FindMessage("job", index, &job)
== B_OK;
- index++) {
- _AddJob(false, job);
+ BMessage targetMessage;
+ for (int32 index = 0; message.FindMessage("target", index,
+ &targetMessage) == B_OK; index++) {
+ const char* name = targetMessage.GetString("name");
+ if (name == NULL) {
+ // TODO: log error
+ debug_printf("Target has no name, ignoring
it!\n");
+ continue;
+ }
+
+ Target* target = FindTarget(name);
+ if (target == NULL) {
+ target = new Target(name);
+ _AddTarget(target);
+ } else if (targetMessage.GetBool("reset")) {
+ // Remove all jobs from this target
+ for (JobMap::iterator iterator = fJobs.begin();
+ iterator != fJobs.end();) {
+ Job* job = iterator->second;
+ JobMap::iterator remove = iterator++;
+
+ if (job->Target() == target) {
+ fJobs.erase(remove);
+ delete job;
+ }
+ }
+ }
+
+ _AddJobs(target, targetMessage);
}
}

@@ -810,7 +1031,23 @@ LaunchDaemon::_ReadFile(const char* context, BEntry&
entry)


void
-LaunchDaemon::_AddJob(bool service, BMessage& message)
+LaunchDaemon::_AddJobs(Target* target, BMessage& message)
+{
+ BMessage job;
+ for (int32 index = 0; message.FindMessage("service", index,
+ &job) == B_OK; index++) {
+ _AddJob(target, true, job);
+ }
+
+ for (int32 index = 0; message.FindMessage("job", index, &job) == B_OK;
+ index++) {
+ _AddJob(target, false, job);
+ }
+}
+
+
+void
+LaunchDaemon::_AddJob(Target* target, bool service, BMessage& message)
{
BString name = message.GetString("name");
if (name.IsEmpty()) {
@@ -828,6 +1065,7 @@ LaunchDaemon::_AddJob(bool service, BMessage& message)
job->SetCreateDefaultPort(!message.GetBool("legacy", !service));
job->SetLaunchInSafeMode(
!message.GetBool("no_safemode", !job->LaunchInSafeMode()));
+ job->SetTarget(target);

BMessage portMessage;
for (int32 index = 0;
@@ -847,13 +1085,15 @@ LaunchDaemon::_AddJob(bool service, BMessage& message)
index++) {
job->AddRequirement(requirement);
}
+ if (fInitTarget != NULL)
+ job->AddRequirement(fInitTarget->Name());

fJobs.insert(std::pair<BString, Job*>(job->Name(), job));
}


void
-LaunchDaemon::_InitJobs(Target* target)
+LaunchDaemon::_InitJobs()
{
for (JobMap::iterator iterator = fJobs.begin(); iterator !=
fJobs.end();) {
Job* job = iterator->second;
@@ -862,7 +1102,7 @@ LaunchDaemon::_InitJobs(Target* target)
status_t status = B_NO_INIT;
if (job->IsEnabled() && (!_IsSafeMode() ||
job->LaunchInSafeMode())) {
std::set<BString> dependencies;
- status = job->Init(target, *this, dependencies);
+ status = job->Init(*this, dependencies);
}

if (status != B_OK) {
@@ -874,18 +1114,20 @@ LaunchDaemon::_InitJobs(Target* target)

// Remove jobs that won't be used later on
fJobs.erase(remove);
+ delete job;
}
}
}


void
-LaunchDaemon::_LaunchJobs()
+LaunchDaemon::_LaunchJobs(Target* target)
{
for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end();
iterator++) {
Job* job = iterator->second;
- _AddLaunchJob(job);
+ if (job->Target() == target)
+ _AddLaunchJob(job);
}
}

@@ -898,6 +1140,13 @@ LaunchDaemon::_AddLaunchJob(Job* job)
}


+void
+LaunchDaemon::_AddTarget(Target* target)
+{
+ fTargets.insert(std::make_pair(target->Title(), target));
+}
+
+
status_t
LaunchDaemon::_StartSession(const char* login, const char* password)
{

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

Commit: cc66427371e5f6791c18198cb545579d7b148710
Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date: Mon Jun 15 17:21:29 2015 UTC

launch_daemon: Moved Job+Target into separate files.

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

diff --git a/src/servers/launch/Jamfile b/src/servers/launch/Jamfile
index df2833c..637e649 100644
--- a/src/servers/launch/Jamfile
+++ b/src/servers/launch/Jamfile
@@ -8,6 +8,8 @@ UseHeaders [ FDirName $(HAIKU_TOP) src bin multiuser ] ;
Server launch_daemon
:
LaunchDaemon.cpp
+ Job.cpp
+ Target.cpp
Worker.cpp

# init jobs
diff --git a/src/servers/launch/Job.cpp b/src/servers/launch/Job.cpp
new file mode 100644
index 0000000..01a6fdb
--- /dev/null
+++ b/src/servers/launch/Job.cpp
@@ -0,0 +1,407 @@
+/*
+ * Copyright 2015, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "Job.h"
+
+#include <Entry.h>
+#include <Looper.h>
+#include <Message.h>
+
+#include "Target.h"
+
+
+Job::Job(const char* name)
+ :
+ BJob(name),
+ fEnabled(true),
+ fService(false),
+ fCreateDefaultPort(false),
+ fLaunchInSafeMode(true),
+ fInitStatus(B_NO_INIT),
+ fTeam(-1),
+ fTarget(NULL)
+{
+}
+
+
+Job::Job(const Job& other)
+ :
+ BJob(other.Name()),
+ fEnabled(other.IsEnabled()),
+ fService(other.IsService()),
+ fCreateDefaultPort(other.CreateDefaultPort()),
+ fLaunchInSafeMode(other.LaunchInSafeMode()),
+ fInitStatus(B_NO_INIT),
+ fTeam(-1),
+ fTarget(other.Target())
+{
+ for (int32 i = 0; i < other.Arguments().CountStrings(); i++)
+ AddArgument(other.Arguments().StringAt(i));
+
+ for (int32 i = 0; i < other.Requirements().CountStrings(); i++)
+ AddRequirement(other.Requirements().StringAt(i));
+
+ PortMap::const_iterator constIterator = other.Ports().begin();
+ for (; constIterator != other.Ports().end(); constIterator++) {
+ fPortMap.insert(
+ std::make_pair(constIterator->first,
constIterator->second));
+ }
+
+ PortMap::iterator iterator = fPortMap.begin();
+ for (; iterator != fPortMap.end(); iterator++)
+ iterator->second.RemoveData("port");
+}
+
+
+Job::~Job()
+{
+ _DeletePorts();
+}
+
+
+const char*
+Job::Name() const
+{
+ return Title().String();
+}
+
+
+bool
+Job::IsEnabled() const
+{
+ return fEnabled;
+}
+
+
+void
+Job::SetEnabled(bool enable)
+{
+ fEnabled = enable;
+}
+
+
+bool
+Job::IsService() const
+{
+ return fService;
+}
+
+
+void
+Job::SetService(bool service)
+{
+ fService = service;
+}
+
+
+bool
+Job::CreateDefaultPort() const
+{
+ return fCreateDefaultPort;
+}
+
+
+void
+Job::SetCreateDefaultPort(bool createPort)
+{
+ fCreateDefaultPort = createPort;
+}
+
+
+void
+Job::AddPort(BMessage& data)
+{
+ const char* name = data.GetString("name");
+ fPortMap.insert(std::pair<BString, BMessage>(BString(name), data));
+}
+
+
+bool
+Job::LaunchInSafeMode() const
+{
+ return fLaunchInSafeMode;
+}
+
+
+void
+Job::SetLaunchInSafeMode(bool launch)
+{
+ fLaunchInSafeMode = launch;
+}
+
+
+const BStringList&
+Job::Arguments() const
+{
+ return fArguments;
+}
+
+
+BStringList&
+Job::Arguments()
+{
+ return fArguments;
+}
+
+
+void
+Job::AddArgument(const char* argument)
+{
+ fArguments.Add(argument);
+}
+
+
+::Target*
+Job::Target() const
+{
+ return fTarget;
+}
+
+
+void
+Job::SetTarget(::Target* target)
+{
+ fTarget = target;
+}
+
+
+const BStringList&
+Job::Requirements() const
+{
+ return fRequirements;
+}
+
+
+BStringList&
+Job::Requirements()
+{
+ return fRequirements;
+}
+
+
+void
+Job::AddRequirement(const char* requirement)
+{
+ fRequirements.Add(requirement);
+}
+
+
+status_t
+Job::Init(const Finder& finder, std::set<BString>& dependencies)
+{
+ // Only initialize the jobs once
+ if (fInitStatus != B_NO_INIT)
+ return fInitStatus;
+
+ fInitStatus = B_OK;
+
+ if (fTarget != NULL)
+ fTarget->AddDependency(this);
+
+ // Check dependencies
+
+ for (int32 index = 0; index < Requirements().CountStrings(); index++) {
+ const BString& requires = Requirements().StringAt(index);
+ if (dependencies.find(requires) != dependencies.end()) {
+ // Found a cyclic dependency
+ // TODO: log error
+ return fInitStatus = B_ERROR;
+ }
+ dependencies.insert(requires);
+
+ Job* dependency = finder.FindJob(requires);
+ if (dependency != NULL) {
+ std::set<BString> subDependencies = dependencies;
+
+ fInitStatus = dependency->Init(finder, subDependencies);
+ if (fInitStatus != B_OK) {
+ // TODO: log error
+ return fInitStatus;
+ }
+
+ fInitStatus = _AddRequirement(dependency);
+ } else {
+ ::Target* target = finder.FindTarget(requires);
+ if (target != NULL)
+ fInitStatus = _AddRequirement(dependency);
+ else {
+ // Could not find dependency
+ fInitStatus = B_NAME_NOT_FOUND;
+ }
+ }
+ if (fInitStatus != B_OK) {
+ // TODO: log error
+ return fInitStatus;
+ }
+ }
+
+ // Create ports
+ // TODO: prefix system ports with "system:"
+
+ bool defaultPort = false;
+
+ for (PortMap::iterator iterator = fPortMap.begin();
+ iterator != fPortMap.end(); iterator++) {
+ BString name(Name());
+ const char* suffix = iterator->second.GetString("name");
+ if (suffix != NULL)
+ name << ':' << suffix;
+ else
+ defaultPort = true;
+
+ const int32 capacity = iterator->second.GetInt32("capacity",
+ B_LOOPER_PORT_DEFAULT_CAPACITY);
+
+ port_id port = create_port(capacity, name.String());
+ if (port < 0) {
+ fInitStatus = port;
+ break;
+ }
+ iterator->second.SetInt32("port", port);
+ }
+
+ if (fInitStatus == B_OK && fCreateDefaultPort && !defaultPort) {
+ BMessage data;
+ data.AddInt32("capacity", B_LOOPER_PORT_DEFAULT_CAPACITY);
+
+ port_id port = create_port(B_LOOPER_PORT_DEFAULT_CAPACITY,
Name());
+ if (port < 0) {
+ // TODO: log error
+ fInitStatus = port;
+ } else {
+ data.SetInt32("port", port);
+ AddPort(data);
+ }
+ }
+
+ return fInitStatus;
+}
+
+
+status_t
+Job::InitCheck() const
+{
+ return fInitStatus;
+}
+
+
+team_id
+Job::Team() const
+{
+ return fTeam;
+}
+
+
+const PortMap&
+Job::Ports() const
+{
+ return fPortMap;
+}
+
+
+port_id
+Job::Port(const char* name) const
+{
+ PortMap::const_iterator found = fPortMap.find(name);
+ if (found != fPortMap.end())
+ return found->second.GetInt32("port", -1);
+
+ return B_NAME_NOT_FOUND;
+}
+
+
+status_t
+Job::Launch()
+{
+ if (fArguments.IsEmpty()) {
+ // TODO: Launch via signature
+ // We cannot use the BRoster here as it tries to pre-register
+ // the application.
+ BString signature("application/");
+ signature << Name();
+ return B_NOT_SUPPORTED;
+ //return be_roster->Launch(signature.String(), (BMessage*)NULL,
&fTeam);
+ }
+
+ entry_ref ref;
+ status_t status = get_ref_for_path(fArguments.StringAt(0).String(),
&ref);
+ if (status != B_OK)
+ return status;
+
+ size_t count = fArguments.CountStrings();
+ const char* args[count + 1];
+ for (int32 i = 0; i < fArguments.CountStrings(); i++) {
+ args[i] = fArguments.StringAt(i);
+ }
+ args[count] = NULL;
+
+ thread_id thread = load_image(count, args,
+ const_cast<const char**>(environ));
+ if (thread >= 0)
+ resume_thread(thread);
+
+ thread_info info;
+ if (get_thread_info(thread, &info) == B_OK)
+ fTeam = info.team;
+ return B_OK;
+// return be_roster->Launch(&ref, count, args, &fTeam);
+}
+
+
+bool
+Job::IsLaunched() const
+{
+ return fTeam >= 0;
+}
+
+
+status_t
+Job::Execute()
+{
+ if (!IsLaunched())
+ return Launch();
+
+ return B_OK;
+}
+
+
+void
+Job::_DeletePorts()
+{
+ PortMap::const_iterator iterator = Ports().begin();
+ for (; iterator != Ports().end(); iterator++) {
+ port_id port = iterator->second.GetInt32("port", -1);
+ if (port >= 0)
+ delete_port(port);
+ }
+}
+
+
+status_t
+Job::_AddRequirement(BJob* dependency)
+{
+ if (dependency == NULL)
+ return B_OK;
+
+ switch (dependency->State()) {
+ case B_JOB_STATE_WAITING_TO_RUN:
+ case B_JOB_STATE_STARTED:
+ case B_JOB_STATE_IN_PROGRESS:
+ AddDependency(dependency);
+ break;
+
+ case B_JOB_STATE_SUCCEEDED:
+ // Just queue it without any dependencies
+ break;
+
+ case B_JOB_STATE_FAILED:
+ case B_JOB_STATE_ABORTED:
+ // TODO: return appropriate error
+ return B_BAD_VALUE;
+ }
+
+ return B_OK;
+}
diff --git a/src/servers/launch/Job.h b/src/servers/launch/Job.h
new file mode 100644
index 0000000..0175556
--- /dev/null
+++ b/src/servers/launch/Job.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2015, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef JOB_H
+#define JOB_H
+
+
+#include <Job.h>
+
+#include <map>
+#include <set>
+
+#include <OS.h>
+#include <StringList.h>
+
+
+using namespace BSupportKit;
+class BMessage;
+
+class Finder;
+class Target;
+
+
+typedef std::map<BString, BMessage> PortMap;
+
+
+class Job : public BJob {
+public:
+ Job(const char*
name);
+ Job(const Job&
other);
+ virtual ~Job();
+
+ const char* Name() const;
+
+ bool IsEnabled() const;
+ void SetEnabled(bool enable);
+
+ bool IsService() const;
+ void SetService(bool
service);
+
+ bool CreateDefaultPort()
const;
+ void
SetCreateDefaultPort(bool createPort);
+
+ void AddPort(BMessage& data);
+
+ bool LaunchInSafeMode()
const;
+ void
SetLaunchInSafeMode(bool launch);
+
+ const BStringList& Arguments() const;
+ BStringList& Arguments();
+ void AddArgument(const char*
argument);
+
+ ::Target* Target() const;
+ void SetTarget(::Target*
target);
+
+ const BStringList& Requirements() const;
+ BStringList& Requirements();
+ void AddRequirement(const
char* requirement);
+
+ status_t Init(const Finder& jobs,
+
std::set<BString>& dependencies);
+ status_t InitCheck() const;
+
+ team_id Team() const;
+
+ const PortMap& Ports() const;
+ port_id Port(const char* name =
NULL) const;
+
+ status_t Launch();
+ bool IsLaunched() const;
+
+protected:
+ virtual status_t Execute();
+
+private:
+ Job& operator=(const Job&
other);
+ void _DeletePorts();
+ status_t _AddRequirement(BJob*
dependency);
+
+private:
+ BStringList fArguments;
+ BStringList fRequirements;
+ bool fEnabled;
+ bool fService;
+ bool fCreateDefaultPort;
+ bool fLaunchInSafeMode;
+ PortMap fPortMap;
+ status_t fInitStatus;
+ team_id fTeam;
+ ::Target* fTarget;
+};
+
+
+class Finder {
+public:
+ virtual Job* FindJob(const char* name) const
= 0;
+ virtual Target* FindTarget(const char* name)
const = 0;
+};
+
+
+#endif // JOB_H
diff --git a/src/servers/launch/LaunchDaemon.cpp
b/src/servers/launch/LaunchDaemon.cpp
index ef57f9e..25d4064 100644
--- a/src/servers/launch/LaunchDaemon.cpp
+++ b/src/servers/launch/LaunchDaemon.cpp
@@ -33,6 +33,8 @@
#include "InitRealTimeClockJob.h"
#include "InitSharedMemoryDirectoryJob.h"
#include "InitTemporaryDirectoryJob.h"
+#include "Job.h"
+#include "Target.h"
#include "Worker.h"


@@ -76,9 +78,6 @@ const static settings_template kSettingsTemplate[] = {
};


-typedef std::map<BString, BMessage> PortMap;
-
-
class Session {
public:
Session(uid_t
user, const BMessenger& target);
@@ -94,101 +93,6 @@ private:
};


-class Target : public BJob {
-public:
- Target(const
char* name);
-
- const char* Name() const;
-
- status_t AddData(const char*
name, BMessage& data);
- const BMessage& Data() const
- {
return fData; }
-
-protected:
- virtual status_t Execute();
-
-private:
- BMessage fData;
-};
-
-
-class Finder;
-
-
-class Job : public BJob {
-public:
- Job(const char*
name);
- Job(const Job&
other);
- virtual ~Job();
-
- const char* Name() const;
-
- bool IsEnabled() const;
- void SetEnabled(bool enable);
-
- bool IsService() const;
- void SetService(bool
service);
-
- bool CreateDefaultPort()
const;
- void
SetCreateDefaultPort(bool createPort);
-
- void AddPort(BMessage& data);
-
- bool LaunchInSafeMode()
const;
- void
SetLaunchInSafeMode(bool launch);
-
- const BStringList& Arguments() const;
- BStringList& Arguments();
- void AddArgument(const char*
argument);
-
- ::Target* Target() const;
- void SetTarget(::Target*
target);
-
- const BStringList& Requirements() const;
- BStringList& Requirements();
- void AddRequirement(const
char* requirement);
-
- status_t Init(const Finder& jobs,
-
std::set<BString>& dependencies);
- status_t InitCheck() const;
-
- team_id Team() const;
-
- const PortMap& Ports() const;
- port_id Port(const char* name =
NULL) const;
-
- status_t Launch();
- bool IsLaunched() const;
-
-protected:
- virtual status_t Execute();
-
-private:
- Job& operator=(const Job&
other);
- void _DeletePorts();
- status_t _AddRequirement(BJob*
dependency);
-
-private:
- BStringList fArguments;
- BStringList fRequirements;
- bool fEnabled;
- bool fService;
- bool fCreateDefaultPort;
- bool fLaunchInSafeMode;
- PortMap fPortMap;
- status_t fInitStatus;
- team_id fTeam;
- ::Target* fTarget;
-};
-
-
-class Finder {
-public:
- virtual Job* FindJob(const char* name) const
= 0;
- virtual Target* FindTarget(const char* name)
const = 0;
-};
-
-
typedef std::map<BString, Job*> JobMap;
typedef std::map<uid_t, Session*> SessionMap;
typedef std::map<BString, Target*> TargetMap;
@@ -259,403 +163,6 @@ get_leaf(const char* signature)
// #pragma mark -


-Job::Job(const char* name)
- :
- BJob(name),
- fEnabled(true),
- fService(false),
- fCreateDefaultPort(false),
- fLaunchInSafeMode(true),
- fInitStatus(B_NO_INIT),
- fTeam(-1),
- fTarget(NULL)
-{
-}
-
-
-Job::Job(const Job& other)
- :
- BJob(other.Name()),
- fEnabled(other.IsEnabled()),
- fService(other.IsService()),
- fCreateDefaultPort(other.CreateDefaultPort()),
- fLaunchInSafeMode(other.LaunchInSafeMode()),
- fInitStatus(B_NO_INIT),
- fTeam(-1),
- fTarget(other.Target())
-{
- for (int32 i = 0; i < other.Arguments().CountStrings(); i++)
- AddArgument(other.Arguments().StringAt(i));
-
- for (int32 i = 0; i < other.Requirements().CountStrings(); i++)
- AddRequirement(other.Requirements().StringAt(i));
-
- PortMap::const_iterator constIterator = other.Ports().begin();
- for (; constIterator != other.Ports().end(); constIterator++) {
- fPortMap.insert(
- std::make_pair(constIterator->first,
constIterator->second));
- }
-
- PortMap::iterator iterator = fPortMap.begin();
- for (; iterator != fPortMap.end(); iterator++)
- iterator->second.RemoveData("port");
-}
-
-
-Job::~Job()
-{
- _DeletePorts();
-}
-
-
-const char*
-Job::Name() const
-{
- return Title().String();
-}
-
-
-bool
-Job::IsEnabled() const
-{
- return fEnabled;
-}
-
-
-void
-Job::SetEnabled(bool enable)
-{
- fEnabled = enable;
-}
-
-
-bool
-Job::IsService() const
-{
- return fService;
-}
-
-
-void
-Job::SetService(bool service)
-{
- fService = service;
-}
-
-
-bool
-Job::CreateDefaultPort() const
-{
- return fCreateDefaultPort;
-}
-
-
-void
-Job::SetCreateDefaultPort(bool createPort)
-{
- fCreateDefaultPort = createPort;
-}
-
-
-void
-Job::AddPort(BMessage& data)
-{
- const char* name = data.GetString("name");
- fPortMap.insert(std::pair<BString, BMessage>(BString(name), data));
-}
-
-
-bool
-Job::LaunchInSafeMode() const
-{
- return fLaunchInSafeMode;
-}
-
-
-void
-Job::SetLaunchInSafeMode(bool launch)
-{
- fLaunchInSafeMode = launch;
-}
-
-
-const BStringList&
-Job::Arguments() const
-{
- return fArguments;
-}
-
-
-BStringList&
-Job::Arguments()
-{
- return fArguments;
-}
-
-
-void
-Job::AddArgument(const char* argument)
-{
- fArguments.Add(argument);
-}
-
-
-::Target*
-Job::Target() const
-{
- return fTarget;
-}
-
-
-void
-Job::SetTarget(::Target* target)
-{
- fTarget = target;
-}
-
-
-const BStringList&
-Job::Requirements() const
-{
- return fRequirements;
-}
-
-
-BStringList&
-Job::Requirements()
-{
- return fRequirements;
-}
-
-
-void
-Job::AddRequirement(const char* requirement)
-{
- fRequirements.Add(requirement);
-}
-
-
-status_t
-Job::Init(const Finder& finder, std::set<BString>& dependencies)
-{
- // Only initialize the jobs once
- if (fInitStatus != B_NO_INIT)
- return fInitStatus;
-
- fInitStatus = B_OK;
-
- if (fTarget != NULL)
- fTarget->AddDependency(this);
-
- // Check dependencies
-
- for (int32 index = 0; index < Requirements().CountStrings(); index++) {
- const BString& requires = Requirements().StringAt(index);
- if (dependencies.find(requires) != dependencies.end()) {
- // Found a cyclic dependency
- // TODO: log error
- return fInitStatus = B_ERROR;
- }
- dependencies.insert(requires);
-
- Job* dependency = finder.FindJob(requires);
- if (dependency != NULL) {
- std::set<BString> subDependencies = dependencies;
-
- fInitStatus = dependency->Init(finder, subDependencies);
- if (fInitStatus != B_OK) {
- // TODO: log error
- return fInitStatus;
- }
-
- fInitStatus = _AddRequirement(dependency);
- } else {
- ::Target* target = finder.FindTarget(requires);
- if (target != NULL)
- fInitStatus = _AddRequirement(dependency);
- else {
- // Could not find dependency
- fInitStatus = B_NAME_NOT_FOUND;
- }
- }
- if (fInitStatus != B_OK) {
- // TODO: log error
- return fInitStatus;
- }
- }
-
- // Create ports
- // TODO: prefix system ports with "system:"
-
- bool defaultPort = false;
-
- for (PortMap::iterator iterator = fPortMap.begin();
- iterator != fPortMap.end(); iterator++) {
- BString name(Name());
- const char* suffix = iterator->second.GetString("name");
- if (suffix != NULL)
- name << ':' << suffix;
- else
- defaultPort = true;
-
- const int32 capacity = iterator->second.GetInt32("capacity",
- B_LOOPER_PORT_DEFAULT_CAPACITY);
-
- port_id port = create_port(capacity, name.String());
- if (port < 0) {
- fInitStatus = port;
- break;
- }
- iterator->second.SetInt32("port", port);
- }
-
- if (fInitStatus == B_OK && fCreateDefaultPort && !defaultPort) {
- BMessage data;
- data.AddInt32("capacity", B_LOOPER_PORT_DEFAULT_CAPACITY);
-
- port_id port = create_port(B_LOOPER_PORT_DEFAULT_CAPACITY,
Name());
- if (port < 0) {
- // TODO: log error
- fInitStatus = port;
- } else {
- data.SetInt32("port", port);
- AddPort(data);
- }
- }
-
- return fInitStatus;
-}
-
-
-status_t
-Job::InitCheck() const
-{
- return fInitStatus;
-}
-
-
-team_id
-Job::Team() const
-{
- return fTeam;
-}
-
-
-const PortMap&
-Job::Ports() const
-{
- return fPortMap;
-}
-
-
-port_id
-Job::Port(const char* name) const
-{
- PortMap::const_iterator found = fPortMap.find(name);
- if (found != fPortMap.end())
- return found->second.GetInt32("port", -1);
-
- return B_NAME_NOT_FOUND;
-}
-
-
-status_t
-Job::Launch()
-{
- if (fArguments.IsEmpty()) {
- // TODO: Launch via signature
- // We cannot use the BRoster here as it tries to pre-register
- // the application.
- BString signature("application/");
- signature << Name();
- return B_NOT_SUPPORTED;
- //return be_roster->Launch(signature.String(), (BMessage*)NULL,
&fTeam);
- }
-
- entry_ref ref;
- status_t status = get_ref_for_path(fArguments.StringAt(0).String(),
&ref);
- if (status != B_OK)
- return status;
-
- size_t count = fArguments.CountStrings();
- const char* args[count + 1];
- for (int32 i = 0; i < fArguments.CountStrings(); i++) {
- args[i] = fArguments.StringAt(i);
- }
- args[count] = NULL;
-
- thread_id thread = load_image(count, args,
- const_cast<const char**>(environ));
- if (thread >= 0)
- resume_thread(thread);
-
- thread_info info;
- if (get_thread_info(thread, &info) == B_OK)
- fTeam = info.team;
- return B_OK;
-// return be_roster->Launch(&ref, count, args, &fTeam);
-}
-
-
-bool
-Job::IsLaunched() const
-{
- return fTeam >= 0;
-}
-
-
-status_t
-Job::Execute()
-{
- if (!IsLaunched())
- return Launch();
-
- return B_OK;
-}
-
-
-void
-Job::_DeletePorts()
-{
- PortMap::const_iterator iterator = Ports().begin();
- for (; iterator != Ports().end(); iterator++) {
- port_id port = iterator->second.GetInt32("port", -1);
- if (port >= 0)
- delete_port(port);
- }
-}
-
-
-status_t
-Job::_AddRequirement(BJob* dependency)
-{
- if (dependency == NULL)
- return B_OK;
-
- switch (dependency->State()) {
- case B_JOB_STATE_WAITING_TO_RUN:
- case B_JOB_STATE_STARTED:
- case B_JOB_STATE_IN_PROGRESS:
- AddDependency(dependency);
- break;
-
- case B_JOB_STATE_SUCCEEDED:
- // Just queue it without any dependencies
- break;
-
- case B_JOB_STATE_FAILED:
- case B_JOB_STATE_ABORTED:
- // TODO: return appropriate error
- return B_BAD_VALUE;
- }
-
- return B_OK;
-}
-
-
-// #pragma mark -
-
-
Session::Session(uid_t user, const BMessenger& daemon)
:
fUser(user),
@@ -667,37 +174,6 @@ Session::Session(uid_t user, const BMessenger& daemon)
// #pragma mark -


-Target::Target(const char* name)
- :
- BJob(name)
-{
-}
-
-
-const char*
-Target::Name() const
-{
- return Title().String();
-}
-
-
-status_t
-Target::AddData(const char* name, BMessage& data)
-{
- return fData.AddMessage(name, &data);
-}
-
-
-status_t
-Target::Execute()
-{
- return B_OK;
-}
-
-
-// #pragma mark -
-
-
LaunchDaemon::LaunchDaemon(bool userMode, status_t& error)
:
BServer(kLaunchDaemonSignature, NULL,
diff --git a/src/servers/launch/Target.cpp b/src/servers/launch/Target.cpp
new file mode 100644
index 0000000..6ee87a7
--- /dev/null
+++ b/src/servers/launch/Target.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2015, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "Target.h"
+
+
+Target::Target(const char* name)
+ :
+ BJob(name)
+{
+}
+
+
+const char*
+Target::Name() const
+{
+ return Title().String();
+}
+
+
+status_t
+Target::AddData(const char* name, BMessage& data)
+{
+ return fData.AddMessage(name, &data);
+}
+
+
+status_t
+Target::Execute()
+{
+ return B_OK;
+}
diff --git a/src/servers/launch/Target.h b/src/servers/launch/Target.h
new file mode 100644
index 0000000..546cb94
--- /dev/null
+++ b/src/servers/launch/Target.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2015, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef TARGET_H
+#define TARGET_H
+
+
+#include <Job.h>
+#include <Message.h>
+
+
+using namespace BSupportKit;
+
+
+class Target : public BJob {
+public:
+ Target(const
char* name);
+
+ const char* Name() const;
+
+ status_t AddData(const char*
name, BMessage& data);
+ const BMessage& Data() const
+ {
return fData; }
+
+protected:
+ virtual status_t Execute();
+
+private:
+ BMessage fData;
+};
+
+
+#endif // TARGET_H


Other related posts:

  • » [haiku-commits] BRANCH axeld-github.launch_daemon [cc66427371e5] in src: servers/launch . kits/app - axeld-github . launch_daemon