launch_daemon: Create/inject ports on launch instead of upfront.
The application is now launched suspended and the ports are created and transferred to the launched team before its main thread is resumed. The ports are therefore owned by the launched team instead of the launch_daemon. This is important when sending messages by area, as the port owner is used to determine where the data area needs to be transferred to. This commit therefore fixes #12285. Note that it is still possible to get at the ports with find_port() while they are still owned by the launch_daemon. This should not be a problem however, as these ports are not supposed to be found this way but only through BLaunchRoster::GetData(), which is synchronized with the above process. Creating the ports in the launch_daemon still has the benefit of returning valid communication ports earlier, i.e. without having to wait for the launched application to actually become ready.
This commit is contained in:
parent
5b9f6b5485
commit
5cf6c0fd3b
@ -244,50 +244,6 @@ Job::Init(const Finder& finder, std::set<BString>& dependencies)
|
||||
}
|
||||
}
|
||||
|
||||
// Create ports
|
||||
// TODO: prefix system ports with "system:"
|
||||
|
||||
bool defaultPort = false;
|
||||
|
||||
for (PortMap::iterator iterator = fPortMap.begin();
|
||||
iterator != fPortMap.end(); iterator++) {
|
||||
BString name(Name());
|
||||
const char* suffix = iterator->second.GetString("name");
|
||||
if (suffix != NULL)
|
||||
name << ':' << suffix;
|
||||
else
|
||||
defaultPort = true;
|
||||
|
||||
const int32 capacity = iterator->second.GetInt32("capacity",
|
||||
B_LOOPER_PORT_DEFAULT_CAPACITY);
|
||||
|
||||
port_id port = create_port(capacity, name.String());
|
||||
if (port < 0) {
|
||||
fInitStatus = port;
|
||||
break;
|
||||
}
|
||||
iterator->second.SetInt32("port", port);
|
||||
|
||||
if (name == "x-vnd.haiku-registrar:auth") {
|
||||
// Allow the launch_daemon to access the registrar authentication
|
||||
BPrivate::set_registrar_authentication_port(port);
|
||||
}
|
||||
}
|
||||
|
||||
if (fInitStatus == B_OK && fCreateDefaultPort && !defaultPort) {
|
||||
BMessage data;
|
||||
data.AddInt32("capacity", B_LOOPER_PORT_DEFAULT_CAPACITY);
|
||||
|
||||
port_id port = create_port(B_LOOPER_PORT_DEFAULT_CAPACITY, Name());
|
||||
if (port < 0) {
|
||||
// TODO: log error
|
||||
fInitStatus = port;
|
||||
} else {
|
||||
data.SetInt32("port", port);
|
||||
AddPort(data);
|
||||
}
|
||||
}
|
||||
|
||||
return fInitStatus;
|
||||
}
|
||||
|
||||
@ -351,10 +307,7 @@ Job::Launch()
|
||||
BString signature("application/");
|
||||
signature << Name();
|
||||
|
||||
status_t status = BRoster::Private().Launch(signature.String(), NULL,
|
||||
NULL, 0, NULL, &environment[0], &fTeam, NULL, false);
|
||||
_SetLaunchStatus(status);
|
||||
return status;
|
||||
return _Launch(signature.String(), NULL, 0, NULL, &environment[0]);
|
||||
}
|
||||
|
||||
// Build argument vector
|
||||
@ -377,10 +330,7 @@ Job::Launch()
|
||||
}
|
||||
|
||||
// Launch via entry_ref
|
||||
status = BRoster::Private().Launch(NULL, &ref, NULL, count, &args[0],
|
||||
&environment[0], &fTeam, NULL, false);
|
||||
_SetLaunchStatus(status);
|
||||
return status;
|
||||
return _Launch(NULL, &ref, count, &args[0], &environment[0]);
|
||||
}
|
||||
|
||||
|
||||
@ -505,3 +455,80 @@ Job::_SendPendingLaunchDataReplies()
|
||||
|
||||
fPendingLaunchDataReplies.MakeEmpty();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Job::_CreateAndTransferPorts()
|
||||
{
|
||||
// TODO: prefix system ports with "system:"
|
||||
|
||||
bool defaultPort = false;
|
||||
|
||||
for (PortMap::iterator iterator = fPortMap.begin();
|
||||
iterator != fPortMap.end(); iterator++) {
|
||||
BString name(Name());
|
||||
const char* suffix = iterator->second.GetString("name");
|
||||
if (suffix != NULL)
|
||||
name << ':' << suffix;
|
||||
else
|
||||
defaultPort = true;
|
||||
|
||||
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;
|
||||
|
||||
status_t result = set_port_owner(port, fTeam);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
iterator->second.SetInt32("port", port);
|
||||
|
||||
if (name == "x-vnd.haiku-registrar:auth") {
|
||||
// Allow the launch_daemon to access the registrar authentication
|
||||
BPrivate::set_registrar_authentication_port(port);
|
||||
}
|
||||
}
|
||||
|
||||
if (fCreateDefaultPort && !defaultPort) {
|
||||
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;
|
||||
|
||||
status_t result = set_port_owner(port, fTeam);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
data.SetInt32("port", port);
|
||||
AddPort(data);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
if (result == B_OK) {
|
||||
result = _CreateAndTransferPorts();
|
||||
|
||||
if (result == B_OK)
|
||||
resume_thread(mainThread);
|
||||
else
|
||||
kill_thread(mainThread);
|
||||
}
|
||||
|
||||
_SetLaunchStatus(result);
|
||||
return result;
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ class BMessage;
|
||||
class Finder;
|
||||
class Target;
|
||||
|
||||
struct entry_ref;
|
||||
|
||||
|
||||
typedef std::map<BString, BMessage> PortMap;
|
||||
|
||||
@ -87,6 +89,12 @@ private:
|
||||
status_t _SendLaunchDataReply(BMessage* message);
|
||||
void _SendPendingLaunchDataReplies();
|
||||
|
||||
status_t _CreateAndTransferPorts();
|
||||
|
||||
status_t _Launch(const char* signature, entry_ref* ref,
|
||||
int argCount, const char* const* args,
|
||||
const char** environment);
|
||||
|
||||
private:
|
||||
BStringList fArguments;
|
||||
BStringList fRequirements;
|
||||
|
Loading…
x
Reference in New Issue
Block a user