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),
|
fLaunching(false),
|
||||||
fInitStatus(B_NO_INIT),
|
fInitStatus(B_NO_INIT),
|
||||||
fTeam(-1),
|
fTeam(-1),
|
||||||
|
fDefaultPort(-1),
|
||||||
fLaunchStatus(B_NO_INIT),
|
fLaunchStatus(B_NO_INIT),
|
||||||
fTarget(NULL),
|
fTarget(NULL),
|
||||||
fPendingLaunchDataReplies(0, false)
|
fPendingLaunchDataReplies(0, false)
|
||||||
@ -47,6 +48,7 @@ Job::Job(const Job& other)
|
|||||||
fLaunching(other.IsLaunching()),
|
fLaunching(other.IsLaunching()),
|
||||||
fInitStatus(B_NO_INIT),
|
fInitStatus(B_NO_INIT),
|
||||||
fTeam(-1),
|
fTeam(-1),
|
||||||
|
fDefaultPort(-1),
|
||||||
fLaunchStatus(B_NO_INIT),
|
fLaunchStatus(B_NO_INIT),
|
||||||
fTarget(other.Target()),
|
fTarget(other.Target()),
|
||||||
fPendingLaunchDataReplies(0, false)
|
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
|
status_t
|
||||||
Job::Launch()
|
Job::Launch()
|
||||||
{
|
{
|
||||||
@ -373,8 +389,12 @@ void
|
|||||||
Job::TeamDeleted()
|
Job::TeamDeleted()
|
||||||
{
|
{
|
||||||
fTeam = -1;
|
fTeam = -1;
|
||||||
|
fDefaultPort = -1;
|
||||||
|
|
||||||
if (IsService())
|
if (IsService())
|
||||||
SetState(B_JOB_STATE_WAITING_TO_RUN);
|
SetState(B_JOB_STATE_WAITING_TO_RUN);
|
||||||
|
|
||||||
|
_SetLaunchStatus(B_NO_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -414,24 +434,12 @@ Job::HandleGetLaunchData(BMessage* message)
|
|||||||
status_t
|
status_t
|
||||||
Job::GetMessenger(BMessenger& messenger)
|
Job::GetMessenger(BMessenger& messenger)
|
||||||
{
|
{
|
||||||
PortMap::const_iterator iterator = fPortMap.begin();
|
if (fDefaultPort < 0)
|
||||||
for (; iterator != fPortMap.end(); iterator++) {
|
return B_NAME_NOT_FOUND;
|
||||||
if (iterator->second.HasString("name"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
port_id port = (port_id)iterator->second.GetInt32("port", -1);
|
BMessenger::Private(messenger).SetTo(fTeam, fDefaultPort,
|
||||||
if (port >= 0) {
|
B_PREFERRED_TOKEN);
|
||||||
BMessenger::Private(messenger).SetTo(fTeam, port,
|
return B_OK;
|
||||||
B_PREFERRED_TOKEN);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is no default port, try roster via signature
|
|
||||||
BString signature = "application/";
|
|
||||||
signature << Name();
|
|
||||||
|
|
||||||
return messenger.SetTo(signature);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -518,9 +526,6 @@ Job::_SetLaunchStatus(status_t launchStatus)
|
|||||||
fLaunchStatus = launchStatus != B_NO_INIT ? launchStatus : B_ERROR;
|
fLaunchStatus = launchStatus != B_NO_INIT ? launchStatus : B_ERROR;
|
||||||
launchLocker.Unlock();
|
launchLocker.Unlock();
|
||||||
|
|
||||||
if (fTeamRegistrator != NULL)
|
|
||||||
fTeamRegistrator->RegisterTeam(this);
|
|
||||||
|
|
||||||
_SendPendingLaunchDataReplies();
|
_SendPendingLaunchDataReplies();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,6 +593,8 @@ Job::_CreateAndTransferPorts()
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
iterator->second.SetInt32("port", port);
|
iterator->second.SetInt32("port", port);
|
||||||
|
if (suffix == NULL)
|
||||||
|
fDefaultPort = port;
|
||||||
|
|
||||||
if (name == "x-vnd.haiku-registrar:auth") {
|
if (name == "x-vnd.haiku-registrar:auth") {
|
||||||
// Allow the launch_daemon to access the registrar authentication
|
// Allow the launch_daemon to access the registrar authentication
|
||||||
@ -608,6 +615,7 @@ Job::_CreateAndTransferPorts()
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
data.SetInt32("port", port);
|
data.SetInt32("port", port);
|
||||||
|
fDefaultPort = port;
|
||||||
AddPort(data);
|
AddPort(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,9 +634,12 @@ Job::_Launch(const char* signature, entry_ref* ref, int argCount,
|
|||||||
if (result == B_OK) {
|
if (result == B_OK) {
|
||||||
result = _CreateAndTransferPorts();
|
result = _CreateAndTransferPorts();
|
||||||
|
|
||||||
if (result == B_OK)
|
if (result == B_OK) {
|
||||||
resume_thread(mainThread);
|
resume_thread(mainThread);
|
||||||
else
|
|
||||||
|
if (fTeamRegistrator != NULL)
|
||||||
|
fTeamRegistrator->RegisterTeam(this);
|
||||||
|
} else
|
||||||
kill_thread(mainThread);
|
kill_thread(mainThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +81,9 @@ public:
|
|||||||
const PortMap& Ports() const;
|
const PortMap& Ports() const;
|
||||||
port_id Port(const char* name = NULL) const;
|
port_id Port(const char* name = NULL) const;
|
||||||
|
|
||||||
|
port_id DefaultPort() const;
|
||||||
|
void SetDefaultPort(port_id port);
|
||||||
|
|
||||||
status_t Launch();
|
status_t Launch();
|
||||||
bool IsLaunched() const;
|
bool IsLaunched() const;
|
||||||
bool IsRunning() const;
|
bool IsRunning() const;
|
||||||
@ -126,6 +129,7 @@ private:
|
|||||||
PortMap fPortMap;
|
PortMap fPortMap;
|
||||||
status_t fInitStatus;
|
status_t fInitStatus;
|
||||||
team_id fTeam;
|
team_id fTeam;
|
||||||
|
port_id fDefaultPort;
|
||||||
status_t fLaunchStatus;
|
status_t fLaunchStatus;
|
||||||
mutex fLaunchStatusLock;
|
mutex fLaunchStatusLock;
|
||||||
::Target* fTarget;
|
::Target* fTarget;
|
||||||
|
@ -232,6 +232,9 @@ private:
|
|||||||
static const char*
|
static const char*
|
||||||
get_leaf(const char* signature)
|
get_leaf(const char* signature)
|
||||||
{
|
{
|
||||||
|
if (signature == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
const char* separator = strrchr(signature, '/');
|
const char* separator = strrchr(signature, '/');
|
||||||
if (separator != NULL)
|
if (separator != NULL)
|
||||||
return separator + 1;
|
return separator + 1;
|
||||||
@ -469,6 +472,9 @@ LaunchDaemon::ReadyToRun()
|
|||||||
if (target != NULL)
|
if (target != NULL)
|
||||||
_LaunchJobs(target);
|
_LaunchJobs(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fUserMode)
|
||||||
|
be_roster->StartWatching(this, B_REQUEST_LAUNCHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -499,6 +505,41 @@ LaunchDaemon::MessageReceived(BMessage* message)
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
case B_GET_LAUNCH_DATA:
|
||||||
_HandleGetLaunchData(message);
|
_HandleGetLaunchData(message);
|
||||||
@ -1654,7 +1695,11 @@ LaunchDaemon::_StartSession(const char* login)
|
|||||||
// TODO: This leaks the parent application
|
// TODO: This leaks the parent application
|
||||||
be_app = NULL;
|
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;
|
status_t status;
|
||||||
LaunchDaemon* daemon = new LaunchDaemon(true, fEvents, status);
|
LaunchDaemon* daemon = new LaunchDaemon(true, fEvents, status);
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
|
Loading…
Reference in New Issue
Block a user