launch_daemon: Fixed preregister consequences.

* Since the last change, the user launch_daemon would talk to the
  registrar again.
* However, this also caused BRoster::Launch() to preregister the app,
  which messed up our preallocated port.
* BRoster::Private::Launch() now allows to get the port that the
  registrar created in such a case, and the launch_daemon will now just
  use that one as default port.
* This lets us talk to the Deskbar again, and should fix #12455, as
  well as #12454 (again).
This commit is contained in:
Axel Dörfler
2015-11-11 16:04:02 +01:00
parent 2c2ba72cf4
commit 9e73b62749
6 changed files with 80 additions and 38 deletions
+4 -3
View File
@@ -161,7 +161,8 @@ private:
thread_id thread) const; thread_id thread) const;
status_t _SetThreadAndTeam(uint32 entryToken, 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, status_t _CompleteRegistration(team_id team,
thread_id thread, port_id port) const; thread_id thread, port_id port) const;
@@ -183,8 +184,8 @@ private:
const BList* messageList, int argc, const BList* messageList, int argc,
const char* const* args, const char* const* args,
const char** environment, const char** environment,
team_id* appTeam, team_id* _appTeam, thread_id* _appThread,
thread_id* appThread, port_id* _appPort, uint32* _appToken,
bool launchSuspended) const; bool launchSuspended) const;
status_t _UpdateActiveApp(team_id team) const; status_t _UpdateActiveApp(team_id team) const;
+4 -2
View File
@@ -31,9 +31,11 @@ class BRoster::Private {
status_t Launch(const char* mimeType, const entry_ref* ref, status_t Launch(const char* mimeType, const entry_ref* ref,
const BList* messageList, int argc, const char* const* args, const BList* messageList, int argc, const char* const* args,
const char** environment, team_id* appTeam, 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, { 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) status_t ShutDown(bool reboot, bool confirm, bool synchronous)
{ return fRoster->_ShutDown(reboot, confirm, synchronous); } { return fRoster->_ShutDown(reboot, confirm, synchronous); }
+20 -11
View File
@@ -923,7 +923,7 @@ BRoster::Launch(const char* mimeType, BMessage* initialMessage,
messageList.AddItem(initialMessage); messageList.AddItem(initialMessage);
return _LaunchApp(mimeType, NULL, &messageList, 0, NULL, 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 B_BAD_VALUE;
return _LaunchApp(mimeType, NULL, messageList, 0, NULL, 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 B_BAD_VALUE;
return _LaunchApp(mimeType, NULL, NULL, argc, args, (const char**)environ, 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<BMessage*>(initialMessage)); messageList.AddItem(const_cast<BMessage*>(initialMessage));
return _LaunchApp(NULL, ref, &messageList, 0, NULL, (const char**)environ, 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 B_BAD_VALUE;
return _LaunchApp(NULL, ref, messageList, 0, NULL, (const char**)environ, 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 B_BAD_VALUE;
return _LaunchApp(NULL, ref, NULL, argc, args, (const char**)environ, 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 status_t
BRoster::_SetThreadAndTeam(uint32 entryToken, thread_id thread, BRoster::_SetThreadAndTeam(uint32 entryToken, thread_id thread,
team_id team) const team_id team, port_id* _port) const
{ {
status_t error = B_OK; status_t error = B_OK;
@@ -1541,6 +1541,9 @@ BRoster::_SetThreadAndTeam(uint32 entryToken, thread_id thread,
&& reply.FindInt32("error", &error) != B_OK) && reply.FindInt32("error", &error) != B_OK)
error = B_ERROR; error = B_ERROR;
if (error == B_OK && _port != NULL)
*_port = reply.GetInt32("port", -1);
return error; return error;
} }
@@ -1836,8 +1839,8 @@ BRoster::_UpdateActiveApp(team_id team) const
status_t status_t
BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref, BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref,
const BList* messageList, int argc, const char* const* args, const BList* messageList, int argc, const char* const* args,
const char** environment, team_id* _appTeam, const char** environment, team_id* _appTeam, thread_id* _appThread,
thread_id* _appThread, bool launchSuspended) const port_id* _appPort, uint32* _appToken, bool launchSuspended) const
{ {
DBG(OUT("BRoster::_LaunchApp()")); DBG(OUT("BRoster::_LaunchApp()"));
@@ -1866,6 +1869,8 @@ BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref,
ArgVector argVector; ArgVector argVector;
team_id team = -1; team_id team = -1;
thread_id appThread = -1; thread_id appThread = -1;
port_id appPort = -1;
uint32 appToken = 0;
do { do {
// find the app // find the app
@@ -1885,7 +1890,6 @@ BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref,
return error; return error;
// pre-register the app (but ignore scipts) // pre-register the app (but ignore scipts)
uint32 appToken = 0;
app_info appInfo; app_info appInfo;
bool isScript = wasDocument && docRef != NULL && *docRef == appRef; bool isScript = wasDocument && docRef != NULL && *docRef == appRef;
if (!isScript && !fNoRegistrar) { if (!isScript && !fNoRegistrar) {
@@ -1900,6 +1904,7 @@ BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref,
&appInfo); &appInfo);
if (error == B_OK) { if (error == B_OK) {
otherAppFlags = appInfo.flags; otherAppFlags = appInfo.flags;
appPort = appInfo.port;
team = appInfo.team; 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)); DBG(OUT(" load image: %s (%lx)\n", strerror(error), error));
// finish the registration // finish the registration
if (error == B_OK && !isScript && !fNoRegistrar) 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), DBG(OUT(" set thread and team: %s (%lx)\n", strerror(error),
error)); error));
@@ -1996,6 +2001,10 @@ BRoster::_LaunchApp(const char* mimeType, const entry_ref* ref,
if (_appThread != NULL) if (_appThread != NULL)
*_appThread = appThread; *_appThread = appThread;
if (_appPort != NULL)
*_appPort = appPort;
if (_appToken != NULL)
*_appToken = appToken;
} }
DBG(OUT("BRoster::_LaunchApp() done: %s (%lx)\n", DBG(OUT("BRoster::_LaunchApp() done: %s (%lx)\n",
+43 -19
View File
@@ -31,6 +31,7 @@ Job::Job(const char* name)
fInitStatus(B_NO_INIT), fInitStatus(B_NO_INIT),
fTeam(-1), fTeam(-1),
fDefaultPort(-1), fDefaultPort(-1),
fToken((uint32)B_PREFERRED_TOKEN),
fLaunchStatus(B_NO_INIT), fLaunchStatus(B_NO_INIT),
fTarget(NULL), fTarget(NULL),
fPendingLaunchDataReplies(0, false) fPendingLaunchDataReplies(0, false)
@@ -49,6 +50,7 @@ Job::Job(const Job& other)
fInitStatus(B_NO_INIT), fInitStatus(B_NO_INIT),
fTeam(-1), fTeam(-1),
fDefaultPort(-1), fDefaultPort(-1),
fToken((uint32)B_PREFERRED_TOKEN),
fLaunchStatus(B_NO_INIT), fLaunchStatus(B_NO_INIT),
fTarget(other.Target()), fTarget(other.Target()),
fPendingLaunchDataReplies(0, false) fPendingLaunchDataReplies(0, false)
@@ -437,8 +439,7 @@ Job::GetMessenger(BMessenger& messenger)
if (fDefaultPort < 0) if (fDefaultPort < 0)
return B_NAME_NOT_FOUND; return B_NAME_NOT_FOUND;
BMessenger::Private(messenger).SetTo(fTeam, fDefaultPort, BMessenger::Private(messenger).SetTo(fTeam, fDefaultPort, fToken);
B_PREFERRED_TOKEN);
return B_OK; 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 status_t
Job::_CreateAndTransferPorts() Job::_CreateAndTransferPorts()
{ {
@@ -584,17 +589,18 @@ Job::_CreateAndTransferPorts()
const int32 capacity = iterator->second.GetInt32("capacity", const int32 capacity = iterator->second.GetInt32("capacity",
B_LOOPER_PORT_DEFAULT_CAPACITY); B_LOOPER_PORT_DEFAULT_CAPACITY);
port_id port = create_port(capacity, name.String()); port_id port = -1;
if (port < 0) if (suffix != NULL || fDefaultPort < 0) {
return port; port = _CreateAndTransferPort(name.String(), capacity);
if (port < 0)
return port;
status_t result = set_port_owner(port, fTeam); if (suffix == NULL)
if (result != B_OK) fDefaultPort = port;
return result; } else if (suffix == NULL)
port = fDefaultPort;
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
@@ -606,16 +612,18 @@ Job::_CreateAndTransferPorts()
BMessage data; BMessage data;
data.AddInt32("capacity", B_LOOPER_PORT_DEFAULT_CAPACITY); data.AddInt32("capacity", B_LOOPER_PORT_DEFAULT_CAPACITY);
port_id port = create_port(B_LOOPER_PORT_DEFAULT_CAPACITY, Name()); port_id port = -1;
if (port < 0) if (fDefaultPort < 0) {
return port; port = _CreateAndTransferPort(Name(),
B_LOOPER_PORT_DEFAULT_CAPACITY);
if (port < 0)
return port;
status_t result = set_port_owner(port, fTeam); fDefaultPort = port;
if (result != B_OK) } else
return result; port = fDefaultPort;
data.SetInt32("port", port); data.SetInt32("port", port);
fDefaultPort = port;
AddPort(data); 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 status_t
Job::_Launch(const char* signature, entry_ref* ref, int argCount, Job::_Launch(const char* signature, entry_ref* ref, int argCount,
const char* const* args, const char** environment) const char* const* args, const char** environment)
{ {
thread_id mainThread = -1; thread_id mainThread = -1;
status_t result = BRoster::Private().Launch(signature, ref, NULL, argCount, 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) { if (result == B_OK) {
result = _CreateAndTransferPorts(); result = _CreateAndTransferPorts();
+3
View File
@@ -114,6 +114,8 @@ private:
void _SendPendingLaunchDataReplies(); void _SendPendingLaunchDataReplies();
status_t _CreateAndTransferPorts(); status_t _CreateAndTransferPorts();
port_id _CreateAndTransferPort(const char* name,
int32 capacity);
status_t _Launch(const char* signature, entry_ref* ref, status_t _Launch(const char* signature, entry_ref* ref,
int argCount, const char* const* args, int argCount, const char* const* args,
@@ -130,6 +132,7 @@ private:
status_t fInitStatus; status_t fInitStatus;
team_id fTeam; team_id fTeam;
port_id fDefaultPort; port_id fDefaultPort;
uint32 fToken;
status_t fLaunchStatus; status_t fLaunchStatus;
mutex fLaunchStatusLock; mutex fLaunchStatusLock;
::Target* fTarget; ::Target* fTarget;
+6 -3
View File
@@ -544,10 +544,12 @@ TRoster::HandleSetThreadAndTeam(BMessage* request)
PRINT("team: %" B_PRId32 ", thread: %" B_PRId32 ", token: %" B_PRIu32 "\n", PRINT("team: %" B_PRId32 ", thread: %" B_PRId32 ", token: %" B_PRIu32 "\n",
team, thread, token); team, thread, token);
port_id port = -1;
// update the app_info // update the app_info
if (error == B_OK) { if (error == B_OK) {
RosterAppInfo* info = fEarlyPreRegisteredApps.InfoForToken(token); RosterAppInfo* info = fEarlyPreRegisteredApps.InfoForToken(token);
if (info) { if (info != NULL) {
// Set thread and team, create a port for the application and // Set thread and team, create a port for the application and
// move the app_info from the list of the early pre-registered // move the app_info from the list of the early pre-registered
// apps to the list of the (pre-)registered apps. // apps to the list of the (pre-)registered apps.
@@ -555,8 +557,8 @@ TRoster::HandleSetThreadAndTeam(BMessage* request)
info->team = team; info->team = team;
info->thread = thread; info->thread = thread;
// create and transfer the port // create and transfer the port
info->port = create_port(B_REG_APP_LOOPER_PORT_CAPACITY, info->port = port = create_port(B_REG_APP_LOOPER_PORT_CAPACITY,
kRAppLooperPortName); kRAppLooperPortName);
if (info->port < 0) if (info->port < 0)
SET_ERROR(error, info->port); SET_ERROR(error, info->port);
if (error == B_OK) if (error == B_OK)
@@ -595,6 +597,7 @@ TRoster::HandleSetThreadAndTeam(BMessage* request)
// reply to the request // reply to the request
if (error == B_OK) { if (error == B_OK) {
BMessage reply(B_REG_SUCCESS); BMessage reply(B_REG_SUCCESS);
reply.AddInt32("port", port);
request->SendReply(&reply); request->SendReply(&reply);
} else { } else {
BMessage reply(B_REG_ERROR); BMessage reply(B_REG_ERROR);