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 15:42:17 +01:00
parent 2c2ba72cf4
commit 9e73b62749
6 changed files with 80 additions and 38 deletions

View File

@ -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;

View File

@ -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); }

View File

@ -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<BMessage*>(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",

View File

@ -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();

View File

@ -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;

View File

@ -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);