diff --git a/headers/os/app/Roster.h b/headers/os/app/Roster.h index 69a11a7777..5127e5a8ee 100644 --- a/headers/os/app/Roster.h +++ b/headers/os/app/Roster.h @@ -161,7 +161,8 @@ private: thread_id thread) const; status_t _SetThreadAndTeam(uint32 entryToken, - thread_id thread, team_id team) const; + thread_id thread, team_id team, + port_id* _port) const; status_t _CompleteRegistration(team_id team, thread_id thread, port_id port) const; @@ -183,8 +184,8 @@ private: const BList* messageList, int argc, const char* const* args, const char** environment, - team_id* appTeam, - thread_id* appThread, + team_id* _appTeam, thread_id* _appThread, + port_id* _appPort, uint32* _appToken, bool launchSuspended) const; status_t _UpdateActiveApp(team_id team) const; diff --git a/headers/private/app/RosterPrivate.h b/headers/private/app/RosterPrivate.h index 33c2e507c3..251476640b 100644 --- a/headers/private/app/RosterPrivate.h +++ b/headers/private/app/RosterPrivate.h @@ -31,9 +31,11 @@ class BRoster::Private { status_t Launch(const char* mimeType, const entry_ref* ref, const BList* messageList, int argc, const char* const* args, const char** environment, team_id* appTeam, - thread_id* appThread, bool launchSuspended) + thread_id* appThread, port_id* appPort, uint32* appToken, + bool launchSuspended) { return fRoster->_LaunchApp(mimeType, ref, messageList, argc, - args, environment, appTeam, appThread, launchSuspended); } + args, environment, appTeam, appThread, appPort, appToken, + launchSuspended); } status_t ShutDown(bool reboot, bool confirm, bool synchronous) { return fRoster->_ShutDown(reboot, confirm, synchronous); } diff --git a/src/kits/app/Roster.cpp b/src/kits/app/Roster.cpp index a268796126..1f0e98f478 100644 --- a/src/kits/app/Roster.cpp +++ b/src/kits/app/Roster.cpp @@ -923,7 +923,7 @@ BRoster::Launch(const char* mimeType, BMessage* initialMessage, messageList.AddItem(initialMessage); return _LaunchApp(mimeType, NULL, &messageList, 0, NULL, - (const char**)environ, _appTeam, NULL, false); + (const char**)environ, _appTeam, NULL, NULL, NULL, false); } @@ -935,7 +935,7 @@ BRoster::Launch(const char* mimeType, BList* messageList, return B_BAD_VALUE; return _LaunchApp(mimeType, NULL, messageList, 0, NULL, - (const char**)environ, _appTeam, NULL, false); + (const char**)environ, _appTeam, NULL, NULL, NULL, false); } @@ -947,7 +947,7 @@ BRoster::Launch(const char* mimeType, int argc, const char* const* args, return B_BAD_VALUE; return _LaunchApp(mimeType, NULL, NULL, argc, args, (const char**)environ, - _appTeam, NULL, false); + _appTeam, NULL, NULL, NULL, false); } @@ -963,7 +963,7 @@ BRoster::Launch(const entry_ref* ref, const BMessage* initialMessage, messageList.AddItem(const_cast(initialMessage)); return _LaunchApp(NULL, ref, &messageList, 0, NULL, (const char**)environ, - _appTeam, NULL, false); + _appTeam, NULL, NULL, NULL, false); } @@ -975,7 +975,7 @@ BRoster::Launch(const entry_ref* ref, const BList* messageList, return B_BAD_VALUE; return _LaunchApp(NULL, ref, messageList, 0, NULL, (const char**)environ, - appTeam, NULL, false); + appTeam, NULL, NULL, NULL, false); } @@ -987,7 +987,7 @@ BRoster::Launch(const entry_ref* ref, int argc, const char* const* args, return B_BAD_VALUE; return _LaunchApp(NULL, ref, NULL, argc, args, (const char**)environ, - appTeam, NULL, false); + appTeam, NULL, NULL, NULL, false); } @@ -1516,7 +1516,7 @@ BRoster::_SetThread(team_id team, thread_id thread) const */ status_t BRoster::_SetThreadAndTeam(uint32 entryToken, thread_id thread, - team_id team) const + team_id team, port_id* _port) const { status_t error = B_OK; @@ -1541,6 +1541,9 @@ BRoster::_SetThreadAndTeam(uint32 entryToken, thread_id thread, && reply.FindInt32("error", &error) != B_OK) error = B_ERROR; + if (error == B_OK && _port != NULL) + *_port = reply.GetInt32("port", -1); + return error; } @@ -1836,8 +1839,8 @@ BRoster::_UpdateActiveApp(team_id team) const status_t BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref, const BList* messageList, int argc, const char* const* args, - const char** environment, team_id* _appTeam, - thread_id* _appThread, bool launchSuspended) const + const char** environment, team_id* _appTeam, thread_id* _appThread, + port_id* _appPort, uint32* _appToken, bool launchSuspended) const { DBG(OUT("BRoster::_LaunchApp()")); @@ -1866,6 +1869,8 @@ BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref, ArgVector argVector; team_id team = -1; thread_id appThread = -1; + port_id appPort = -1; + uint32 appToken = 0; do { // find the app @@ -1885,7 +1890,6 @@ BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref, return error; // pre-register the app (but ignore scipts) - uint32 appToken = 0; app_info appInfo; bool isScript = wasDocument && docRef != NULL && *docRef == appRef; if (!isScript && !fNoRegistrar) { @@ -1900,6 +1904,7 @@ BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref, &appInfo); if (error == B_OK) { otherAppFlags = appInfo.flags; + appPort = appInfo.port; team = appInfo.team; } } @@ -1927,7 +1932,7 @@ BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref, DBG(OUT(" load image: %s (%lx)\n", strerror(error), error)); // finish the registration if (error == B_OK && !isScript && !fNoRegistrar) - error = _SetThreadAndTeam(appToken, appThread, team); + error = _SetThreadAndTeam(appToken, appThread, team, &appPort); DBG(OUT(" set thread and team: %s (%lx)\n", strerror(error), error)); @@ -1996,6 +2001,10 @@ BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref, if (_appThread != NULL) *_appThread = appThread; + if (_appPort != NULL) + *_appPort = appPort; + if (_appToken != NULL) + *_appToken = appToken; } DBG(OUT("BRoster::_LaunchApp() done: %s (%lx)\n", diff --git a/src/servers/launch/Job.cpp b/src/servers/launch/Job.cpp index 85c9392de8..9d3c50cead 100644 --- a/src/servers/launch/Job.cpp +++ b/src/servers/launch/Job.cpp @@ -31,6 +31,7 @@ Job::Job(const char* name) fInitStatus(B_NO_INIT), fTeam(-1), fDefaultPort(-1), + fToken((uint32)B_PREFERRED_TOKEN), fLaunchStatus(B_NO_INIT), fTarget(NULL), fPendingLaunchDataReplies(0, false) @@ -49,6 +50,7 @@ Job::Job(const Job& other) fInitStatus(B_NO_INIT), fTeam(-1), fDefaultPort(-1), + fToken((uint32)B_PREFERRED_TOKEN), fLaunchStatus(B_NO_INIT), fTarget(other.Target()), fPendingLaunchDataReplies(0, false) @@ -437,8 +439,7 @@ Job::GetMessenger(BMessenger& messenger) if (fDefaultPort < 0) return B_NAME_NOT_FOUND; - BMessenger::Private(messenger).SetTo(fTeam, fDefaultPort, - B_PREFERRED_TOKEN); + BMessenger::Private(messenger).SetTo(fTeam, fDefaultPort, fToken); return B_OK; } @@ -565,6 +566,10 @@ Job::_SendPendingLaunchDataReplies() } +/*! Creates the ports for a newly launched job. If the registrar already + pre-registered the application, \c fDefaultPort will already be set, and + honored when filling the ports message. +*/ status_t Job::_CreateAndTransferPorts() { @@ -584,17 +589,18 @@ Job::_CreateAndTransferPorts() const int32 capacity = iterator->second.GetInt32("capacity", B_LOOPER_PORT_DEFAULT_CAPACITY); - port_id port = create_port(capacity, name.String()); - if (port < 0) - return port; + port_id port = -1; + if (suffix != NULL || fDefaultPort < 0) { + port = _CreateAndTransferPort(name.String(), capacity); + if (port < 0) + return port; - status_t result = set_port_owner(port, fTeam); - if (result != B_OK) - return result; + if (suffix == NULL) + fDefaultPort = port; + } else if (suffix == NULL) + port = fDefaultPort; 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 @@ -606,16 +612,18 @@ Job::_CreateAndTransferPorts() BMessage data; data.AddInt32("capacity", B_LOOPER_PORT_DEFAULT_CAPACITY); - port_id port = create_port(B_LOOPER_PORT_DEFAULT_CAPACITY, Name()); - if (port < 0) - return port; + port_id port = -1; + if (fDefaultPort < 0) { + port = _CreateAndTransferPort(Name(), + B_LOOPER_PORT_DEFAULT_CAPACITY); + if (port < 0) + return port; - status_t result = set_port_owner(port, fTeam); - if (result != B_OK) - return result; + fDefaultPort = port; + } else + port = fDefaultPort; data.SetInt32("port", port); - fDefaultPort = port; AddPort(data); } @@ -623,14 +631,30 @@ Job::_CreateAndTransferPorts() } +port_id +Job::_CreateAndTransferPort(const char* name, int32 capacity) +{ + port_id port = create_port(B_LOOPER_PORT_DEFAULT_CAPACITY, Name()); + if (port < 0) + return port; + + status_t status = set_port_owner(port, fTeam); + if (status != B_OK) { + delete_port(port); + return status; + } + + return port; +} + + status_t Job::_Launch(const char* signature, entry_ref* ref, int argCount, const char* const* args, const char** environment) { thread_id mainThread = -1; status_t result = BRoster::Private().Launch(signature, ref, NULL, argCount, - args, environment, &fTeam, &mainThread, true); - + args, environment, &fTeam, &mainThread, &fDefaultPort, &fToken, true); if (result == B_OK) { result = _CreateAndTransferPorts(); diff --git a/src/servers/launch/Job.h b/src/servers/launch/Job.h index 06d9f83bc1..d4312956c3 100644 --- a/src/servers/launch/Job.h +++ b/src/servers/launch/Job.h @@ -114,6 +114,8 @@ private: void _SendPendingLaunchDataReplies(); status_t _CreateAndTransferPorts(); + port_id _CreateAndTransferPort(const char* name, + int32 capacity); status_t _Launch(const char* signature, entry_ref* ref, int argCount, const char* const* args, @@ -130,6 +132,7 @@ private: status_t fInitStatus; team_id fTeam; port_id fDefaultPort; + uint32 fToken; status_t fLaunchStatus; mutex fLaunchStatusLock; ::Target* fTarget; diff --git a/src/servers/registrar/TRoster.cpp b/src/servers/registrar/TRoster.cpp index a930adf6c9..e8cd9a8765 100644 --- a/src/servers/registrar/TRoster.cpp +++ b/src/servers/registrar/TRoster.cpp @@ -544,10 +544,12 @@ TRoster::HandleSetThreadAndTeam(BMessage* request) PRINT("team: %" B_PRId32 ", thread: %" B_PRId32 ", token: %" B_PRIu32 "\n", team, thread, token); + port_id port = -1; + // update the app_info if (error == B_OK) { RosterAppInfo* info = fEarlyPreRegisteredApps.InfoForToken(token); - if (info) { + if (info != NULL) { // Set thread and team, create a port for the application and // move the app_info from the list of the early pre-registered // apps to the list of the (pre-)registered apps. @@ -555,8 +557,8 @@ TRoster::HandleSetThreadAndTeam(BMessage* request) info->team = team; info->thread = thread; // create and transfer the port - info->port = create_port(B_REG_APP_LOOPER_PORT_CAPACITY, - kRAppLooperPortName); + info->port = port = create_port(B_REG_APP_LOOPER_PORT_CAPACITY, + kRAppLooperPortName); if (info->port < 0) SET_ERROR(error, info->port); if (error == B_OK) @@ -595,6 +597,7 @@ TRoster::HandleSetThreadAndTeam(BMessage* request) // reply to the request if (error == B_OK) { BMessage reply(B_REG_SUCCESS); + reply.AddInt32("port", port); request->SendReply(&reply); } else { BMessage reply(B_REG_ERROR);