* Fixed a possible endless loop: when the calling team should receive the B_REFS_RECEIVED

message, we no longer send a message. This seems to be what BeOS does, and it prevents
  Tracker from playing ping-pong when trying opening generic files.
* Eliminated superfluous otherTeam & targetTeam variables in _LaunchApp().
* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16564 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-03-02 12:30:12 +00:00
parent 4b6321235c
commit bc2f09bb77
+46 -29
View File
@@ -1724,27 +1724,36 @@ BRoster::_RemoveApp(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 BList *messageList, int argc,
const char *const *args, team_id *appTeam) const const char *const *args, team_id *_appTeam) const
{ {
DBG(OUT("BRoster::xLaunchAppPrivate()")); DBG(OUT("BRoster::_LaunchApp()"));
status_t error = (mimeType || ref ? B_OK : B_BAD_VALUE);
if (_appTeam != NULL) {
// we're supposed to set _appTeam to -1 on error; we'll
// reset it later if everything goes well
*_appTeam = -1;
}
if (mimeType == NULL && ref == NULL)
return B_BAD_VALUE;
// use a mutable copy of the document entry_ref // use a mutable copy of the document entry_ref
entry_ref _docRef; entry_ref _docRef;
entry_ref *docRef = NULL; entry_ref *docRef = NULL;
if (error == B_OK && ref) { if (ref != NULL) {
_docRef = *ref; _docRef = *ref;
docRef = &_docRef; docRef = &_docRef;
} }
// find the app // find the app
entry_ref appRef; entry_ref appRef;
char signature[B_MIME_TYPE_LENGTH]; char signature[B_MIME_TYPE_LENGTH];
uint32 appFlags = B_REG_DEFAULT_APP_FLAGS; uint32 appFlags = B_REG_DEFAULT_APP_FLAGS;
bool wasDocument = true; bool wasDocument = true;
if (error == B_OK) { status_t error = _ResolveApp(mimeType, docRef, &appRef, signature, &appFlags,
error = _ResolveApp(mimeType, docRef, &appRef, signature, &appFlags,
&wasDocument); &wasDocument);
}
DBG(OUT(" find app: %s (%lx)\n", strerror(error), error)); DBG(OUT(" find app: %s (%lx)\n", strerror(error), error));
// build an argument vector // build an argument vector
ArgVector argVector; ArgVector argVector;
if (error == B_OK) { if (error == B_OK) {
@@ -1752,27 +1761,28 @@ BRoster::_LaunchApp(const char *mimeType, const entry_ref *ref,
(wasDocument ? docRef : NULL)); (wasDocument ? docRef : NULL));
} }
DBG(OUT(" build argv: %s (%lx)\n", strerror(error), error)); DBG(OUT(" build argv: %s (%lx)\n", strerror(error), error));
// pre-register the app // pre-register the app
app_info appInfo; app_info appInfo;
bool alreadyRunning = false; bool alreadyRunning = false;
uint32 appToken = 0; uint32 appToken = 0;
team_id otherTeam = -1; team_id team = -1;
uint32 otherAppFlags = B_REG_DEFAULT_APP_FLAGS; uint32 otherAppFlags = B_REG_DEFAULT_APP_FLAGS;
if (error == B_OK && !alreadyRunning) { if (error == B_OK && !alreadyRunning) {
error = _AddApplication(signature, &appRef, appFlags, -1, -1, -1, false, error = _AddApplication(signature, &appRef, appFlags, -1, -1, -1, false,
&appToken, &otherTeam); &appToken, &team);
if (error == B_ALREADY_RUNNING) { if (error == B_ALREADY_RUNNING) {
DBG(OUT(" already running\n")); DBG(OUT(" already running\n"));
alreadyRunning = true; alreadyRunning = true;
error = B_OK; error = B_OK;
// get the app flags for the running application // get the app flags for the running application
if (GetRunningAppInfo(otherTeam, &appInfo) == B_OK) if (GetRunningAppInfo(team, &appInfo) == B_OK)
otherAppFlags = appInfo.flags; otherAppFlags = appInfo.flags;
} }
} }
DBG(OUT(" pre-register: %s (%lx)\n", strerror(error), error)); DBG(OUT(" pre-register: %s (%lx)\n", strerror(error), error));
// launch the app // launch the app
team_id team = -1;
if (error == B_OK && !alreadyRunning) { if (error == B_OK && !alreadyRunning) {
DBG(OUT(" token: %lu\n", appToken)); DBG(OUT(" token: %lu\n", appToken));
// load the app image // load the app image
@@ -1810,10 +1820,14 @@ BRoster::_LaunchApp(const char *mimeType, const entry_ref *ref,
} }
} }
if (alreadyRunning && current_team() == team) {
// The target team is calling us, so we don't send it the message
// to prevent an endless loop
error = B_BAD_VALUE;
}
// send "on launch" messages // send "on launch" messages
if (error == B_OK) { if (error == B_OK) {
// the messages go to the launched team or to the already running one
team_id targetTeam = (alreadyRunning ? otherTeam : team);
// If the target app is B_ARGV_ONLY almost no messages are sent to it. // If the target app is B_ARGV_ONLY almost no messages are sent to it.
// More precisely, the launched app gets at least B_ARGV_RECEIVED and // More precisely, the launched app gets at least B_ARGV_RECEIVED and
// B_READY_TO_RUN, an already running app gets nothing. // B_READY_TO_RUN, an already running app gets nothing.
@@ -1822,19 +1836,21 @@ BRoster::_LaunchApp(const char *mimeType, const entry_ref *ref,
const BList *_messageList = (argvOnly ? NULL : messageList); const BList *_messageList = (argvOnly ? NULL : messageList);
// don't send ref, if it refers to the app or is included in the // don't send ref, if it refers to the app or is included in the
// argument vector // argument vector
const entry_ref *_ref = (argvOnly || !wasDocument const entry_ref *_ref = argvOnly || !wasDocument
|| argVector.Count() > 1 ? NULL : docRef); || argVector.Count() > 1 ? NULL : docRef;
if (!(argvOnly && alreadyRunning)) { if (!(argvOnly && alreadyRunning)) {
_SendToRunning(targetTeam, argVector.Count(), argVector.Args(), _SendToRunning(team, argVector.Count(), argVector.Args(),
_messageList, _ref, !alreadyRunning); _messageList, _ref, !alreadyRunning);
} }
} }
// set return values // set return values
if (error == B_OK && alreadyRunning) if (error == B_OK) {
if (alreadyRunning)
error = B_ALREADY_RUNNING; error = B_ALREADY_RUNNING;
if (appTeam) else if (_appTeam)
*appTeam = (error == B_OK ? team : -1); *_appTeam = team;
}
DBG(OUT("BRoster::_LaunchApp() done: %s (%lx)\n", DBG(OUT("BRoster::_LaunchApp() done: %s (%lx)\n",
strerror(error), error)); strerror(error), error));
@@ -1998,12 +2014,12 @@ BRoster::_TranslateRef(entry_ref *ref, BMimeType *appMeta,
entry_ref *appRef, BFile *appFile, entry_ref *appRef, BFile *appFile,
bool *wasDocument) const bool *wasDocument) const
{ {
status_t error = (ref && appMeta && appRef && appFile ? B_OK if (ref == NULL || appMeta == NULL || appRef == NULL || appFile == NULL)
: B_BAD_VALUE); return B_BAD_VALUE;
// resolve ref, if necessary // resolve ref, if necessary
if (error == B_OK) {
BEntry entry; BEntry entry;
error = entry.SetTo(ref, false); status_t error = entry.SetTo(ref, false);
if (error == B_OK && entry.IsSymLink()) { if (error == B_OK && entry.IsSymLink()) {
// ref refers to a link // ref refers to a link
error = entry.SetTo(ref, true); error = entry.SetTo(ref, true);
@@ -2012,7 +2028,7 @@ BRoster::_TranslateRef(entry_ref *ref, BMimeType *appMeta,
if (error != B_OK) if (error != B_OK)
error = B_LAUNCH_FAILED_NO_RESOLVE_LINK; error = B_LAUNCH_FAILED_NO_RESOLVE_LINK;
} }
}
// init node // init node
BNode node; BNode node;
if (error == B_OK) if (error == B_OK)
@@ -2095,13 +2111,14 @@ status_t
BRoster::_TranslateType(const char *mimeType, BMimeType *appMeta, BRoster::_TranslateType(const char *mimeType, BMimeType *appMeta,
entry_ref *appRef, BFile *appFile) const entry_ref *appRef, BFile *appFile) const
{ {
status_t error = (mimeType && appMeta && appRef && appFile if (mimeType == NULL || appMeta == NULL || appRef == NULL
&& strlen(mimeType) < B_MIME_TYPE_LENGTH ? B_OK || appFile == NULL || strlen(mimeType) >= B_MIME_TYPE_LENGTH)
: B_BAD_VALUE); return B_BAD_VALUE;
// create a BMimeType and check, if the type is installed // create a BMimeType and check, if the type is installed
BMimeType type; BMimeType type;
if (error == B_OK) status_t error = type.SetTo(mimeType);
error = type.SetTo(mimeType);
// get the preferred app // get the preferred app
char appSignature[B_MIME_TYPE_LENGTH]; char appSignature[B_MIME_TYPE_LENGTH];
if (error == B_OK) { if (error == B_OK) {