diff --git a/src/servers/launch/Job.cpp b/src/servers/launch/Job.cpp index 2c5ad6f3fa..85c9392de8 100644 --- a/src/servers/launch/Job.cpp +++ b/src/servers/launch/Job.cpp @@ -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); } diff --git a/src/servers/launch/Job.h b/src/servers/launch/Job.h index 3995cf2848..06d9f83bc1 100644 --- a/src/servers/launch/Job.h +++ b/src/servers/launch/Job.h @@ -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; diff --git a/src/servers/launch/LaunchDaemon.cpp b/src/servers/launch/LaunchDaemon.cpp index e18d165de9..36a4a5647c 100644 --- a/src/servers/launch/LaunchDaemon.cpp +++ b/src/servers/launch/LaunchDaemon.cpp @@ -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)