launch_daemon: Retrieve default port from monitoring BRoster.
* Instead, we now maintain a default port for a job. For "legacy" services, BRoster's B_SOME_APP_LAUNCHED will update it, too. * This allows to quit Tracker using "launch_roster stop". * Also, this fixes bug #12249, as we don't use the signature variant of creating BMessenger anymore in Job::GetMessenger(). This would call into the launch_daemon again, and deadlock.
This commit is contained in:
parent
c1a27ee107
commit
70708ef97d
@ -30,6 +30,7 @@ Job::Job(const char* name)
|
||||
fLaunching(false),
|
||||
fInitStatus(B_NO_INIT),
|
||||
fTeam(-1),
|
||||
fDefaultPort(-1),
|
||||
fLaunchStatus(B_NO_INIT),
|
||||
fTarget(NULL),
|
||||
fPendingLaunchDataReplies(0, false)
|
||||
@ -47,6 +48,7 @@ Job::Job(const Job& other)
|
||||
fLaunching(other.IsLaunching()),
|
||||
fInitStatus(B_NO_INIT),
|
||||
fTeam(-1),
|
||||
fDefaultPort(-1),
|
||||
fLaunchStatus(B_NO_INIT),
|
||||
fTarget(other.Target()),
|
||||
fPendingLaunchDataReplies(0, false)
|
||||
@ -298,6 +300,20 @@ Job::Port(const char* name) const
|
||||
}
|
||||
|
||||
|
||||
port_id
|
||||
Job::DefaultPort() const
|
||||
{
|
||||
return fDefaultPort;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Job::SetDefaultPort(port_id port)
|
||||
{
|
||||
fDefaultPort = port;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Job::Launch()
|
||||
{
|
||||
@ -373,8 +389,12 @@ void
|
||||
Job::TeamDeleted()
|
||||
{
|
||||
fTeam = -1;
|
||||
fDefaultPort = -1;
|
||||
|
||||
if (IsService())
|
||||
SetState(B_JOB_STATE_WAITING_TO_RUN);
|
||||
|
||||
_SetLaunchStatus(B_NO_INIT);
|
||||
}
|
||||
|
||||
|
||||
@ -414,24 +434,12 @@ Job::HandleGetLaunchData(BMessage* message)
|
||||
status_t
|
||||
Job::GetMessenger(BMessenger& messenger)
|
||||
{
|
||||
PortMap::const_iterator iterator = fPortMap.begin();
|
||||
for (; iterator != fPortMap.end(); iterator++) {
|
||||
if (iterator->second.HasString("name"))
|
||||
continue;
|
||||
if (fDefaultPort < 0)
|
||||
return B_NAME_NOT_FOUND;
|
||||
|
||||
port_id port = (port_id)iterator->second.GetInt32("port", -1);
|
||||
if (port >= 0) {
|
||||
BMessenger::Private(messenger).SetTo(fTeam, port,
|
||||
B_PREFERRED_TOKEN);
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// There is no default port, try roster via signature
|
||||
BString signature = "application/";
|
||||
signature << Name();
|
||||
|
||||
return messenger.SetTo(signature);
|
||||
BMessenger::Private(messenger).SetTo(fTeam, fDefaultPort,
|
||||
B_PREFERRED_TOKEN);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -518,9 +526,6 @@ Job::_SetLaunchStatus(status_t launchStatus)
|
||||
fLaunchStatus = launchStatus != B_NO_INIT ? launchStatus : B_ERROR;
|
||||
launchLocker.Unlock();
|
||||
|
||||
if (fTeamRegistrator != NULL)
|
||||
fTeamRegistrator->RegisterTeam(this);
|
||||
|
||||
_SendPendingLaunchDataReplies();
|
||||
}
|
||||
|
||||
@ -588,6 +593,8 @@ Job::_CreateAndTransferPorts()
|
||||
return result;
|
||||
|
||||
iterator->second.SetInt32("port", port);
|
||||
if (suffix == NULL)
|
||||
fDefaultPort = port;
|
||||
|
||||
if (name == "x-vnd.haiku-registrar:auth") {
|
||||
// Allow the launch_daemon to access the registrar authentication
|
||||
@ -608,6 +615,7 @@ Job::_CreateAndTransferPorts()
|
||||
return result;
|
||||
|
||||
data.SetInt32("port", port);
|
||||
fDefaultPort = port;
|
||||
AddPort(data);
|
||||
}
|
||||
|
||||
@ -626,9 +634,12 @@ Job::_Launch(const char* signature, entry_ref* ref, int argCount,
|
||||
if (result == B_OK) {
|
||||
result = _CreateAndTransferPorts();
|
||||
|
||||
if (result == B_OK)
|
||||
if (result == B_OK) {
|
||||
resume_thread(mainThread);
|
||||
else
|
||||
|
||||
if (fTeamRegistrator != NULL)
|
||||
fTeamRegistrator->RegisterTeam(this);
|
||||
} else
|
||||
kill_thread(mainThread);
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,9 @@ public:
|
||||
const PortMap& Ports() const;
|
||||
port_id Port(const char* name = NULL) const;
|
||||
|
||||
port_id DefaultPort() const;
|
||||
void SetDefaultPort(port_id port);
|
||||
|
||||
status_t Launch();
|
||||
bool IsLaunched() const;
|
||||
bool IsRunning() const;
|
||||
@ -126,6 +129,7 @@ private:
|
||||
PortMap fPortMap;
|
||||
status_t fInitStatus;
|
||||
team_id fTeam;
|
||||
port_id fDefaultPort;
|
||||
status_t fLaunchStatus;
|
||||
mutex fLaunchStatusLock;
|
||||
::Target* fTarget;
|
||||
|
@ -232,6 +232,9 @@ private:
|
||||
static const char*
|
||||
get_leaf(const char* signature)
|
||||
{
|
||||
if (signature == NULL)
|
||||
return NULL;
|
||||
|
||||
const char* separator = strrchr(signature, '/');
|
||||
if (separator != NULL)
|
||||
return separator + 1;
|
||||
@ -469,6 +472,9 @@ LaunchDaemon::ReadyToRun()
|
||||
if (target != NULL)
|
||||
_LaunchJobs(target);
|
||||
}
|
||||
|
||||
if (fUserMode)
|
||||
be_roster->StartWatching(this, B_REQUEST_LAUNCHED);
|
||||
}
|
||||
|
||||
|
||||
@ -499,6 +505,41 @@ LaunchDaemon::MessageReceived(BMessage* message)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case B_SOME_APP_LAUNCHED:
|
||||
{
|
||||
team_id team = (team_id)message->GetInt32("be:team", -1);
|
||||
Job* job = NULL;
|
||||
|
||||
MutexLocker locker(fTeamsLock);
|
||||
|
||||
TeamMap::iterator found = fTeams.find(team);
|
||||
if (found != fTeams.end()) {
|
||||
job = found->second;
|
||||
locker.Unlock();
|
||||
} else {
|
||||
locker.Unlock();
|
||||
|
||||
// Find job by name instead
|
||||
const char* signature = message->GetString("be:signature");
|
||||
job = FindJob(get_leaf(signature));
|
||||
if (job != NULL) {
|
||||
TRACE("Updated default port of untracked team %d, %s\n",
|
||||
(int)team, signature);
|
||||
}
|
||||
}
|
||||
|
||||
if (job != NULL) {
|
||||
// Update port info
|
||||
app_info info;
|
||||
status_t status = be_roster->GetRunningAppInfo(team, &info);
|
||||
if (status == B_OK && info.port != job->DefaultPort()) {
|
||||
TRACE("Update default port for %s to %d\n", job->Name(),
|
||||
(int)info.port);
|
||||
job->SetDefaultPort(info.port);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case B_GET_LAUNCH_DATA:
|
||||
_HandleGetLaunchData(message);
|
||||
@ -1654,7 +1695,11 @@ LaunchDaemon::_StartSession(const char* login)
|
||||
// TODO: This leaks the parent application
|
||||
be_app = NULL;
|
||||
|
||||
// TODO: take over system jobs, and reserve their names
|
||||
// Reinitialize be_roster
|
||||
BRoster::Private().DeleteBeRoster();
|
||||
BRoster::Private().InitBeRoster();
|
||||
|
||||
// TODO: take over system jobs, and reserve their names (or ask parent)
|
||||
status_t status;
|
||||
LaunchDaemon* daemon = new LaunchDaemon(true, fEvents, status);
|
||||
if (status == B_OK)
|
||||
|
Loading…
Reference in New Issue
Block a user