* 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

View File

@ -1724,27 +1724,36 @@ BRoster::_RemoveApp(team_id team) const
status_t
BRoster::_LaunchApp(const char *mimeType, const entry_ref *ref,
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()"));
status_t error = (mimeType || ref ? B_OK : B_BAD_VALUE);
DBG(OUT("BRoster::_LaunchApp()"));
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
entry_ref _docRef;
entry_ref *docRef = NULL;
if (error == B_OK && ref) {
if (ref != NULL) {
_docRef = *ref;
docRef = &_docRef;
}
// find the app
entry_ref appRef;
char signature[B_MIME_TYPE_LENGTH];
uint32 appFlags = B_REG_DEFAULT_APP_FLAGS;
bool wasDocument = true;
if (error == B_OK) {
error = _ResolveApp(mimeType, docRef, &appRef, signature, &appFlags,
status_t error = _ResolveApp(mimeType, docRef, &appRef, signature, &appFlags,
&wasDocument);
}
DBG(OUT(" find app: %s (%lx)\n", strerror(error), error));
// build an argument vector
ArgVector argVector;
if (error == B_OK) {
@ -1752,27 +1761,28 @@ BRoster::_LaunchApp(const char *mimeType, const entry_ref *ref,
(wasDocument ? docRef : NULL));
}
DBG(OUT(" build argv: %s (%lx)\n", strerror(error), error));
// pre-register the app
app_info appInfo;
bool alreadyRunning = false;
uint32 appToken = 0;
team_id otherTeam = -1;
team_id team = -1;
uint32 otherAppFlags = B_REG_DEFAULT_APP_FLAGS;
if (error == B_OK && !alreadyRunning) {
error = _AddApplication(signature, &appRef, appFlags, -1, -1, -1, false,
&appToken, &otherTeam);
&appToken, &team);
if (error == B_ALREADY_RUNNING) {
DBG(OUT(" already running\n"));
alreadyRunning = true;
error = B_OK;
// get the app flags for the running application
if (GetRunningAppInfo(otherTeam, &appInfo) == B_OK)
if (GetRunningAppInfo(team, &appInfo) == B_OK)
otherAppFlags = appInfo.flags;
}
}
DBG(OUT(" pre-register: %s (%lx)\n", strerror(error), error));
// launch the app
team_id team = -1;
if (error == B_OK && !alreadyRunning) {
DBG(OUT(" token: %lu\n", appToken));
// 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
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.
// More precisely, the launched app gets at least B_ARGV_RECEIVED and
// 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);
// don't send ref, if it refers to the app or is included in the
// argument vector
const entry_ref *_ref = (argvOnly || !wasDocument
|| argVector.Count() > 1 ? NULL : docRef);
const entry_ref *_ref = argvOnly || !wasDocument
|| argVector.Count() > 1 ? NULL : docRef;
if (!(argvOnly && alreadyRunning)) {
_SendToRunning(targetTeam, argVector.Count(), argVector.Args(),
_SendToRunning(team, argVector.Count(), argVector.Args(),
_messageList, _ref, !alreadyRunning);
}
}
// set return values
if (error == B_OK && alreadyRunning)
error = B_ALREADY_RUNNING;
if (appTeam)
*appTeam = (error == B_OK ? team : -1);
if (error == B_OK) {
if (alreadyRunning)
error = B_ALREADY_RUNNING;
else if (_appTeam)
*_appTeam = team;
}
DBG(OUT("BRoster::_LaunchApp() done: %s (%lx)\n",
strerror(error), error));
@ -1998,21 +2014,21 @@ BRoster::_TranslateRef(entry_ref *ref, BMimeType *appMeta,
entry_ref *appRef, BFile *appFile,
bool *wasDocument) const
{
status_t error = (ref && appMeta && appRef && appFile ? B_OK
: B_BAD_VALUE);
if (ref == NULL || appMeta == NULL || appRef == NULL || appFile == NULL)
return B_BAD_VALUE;
// resolve ref, if necessary
if (error == B_OK) {
BEntry entry;
error = entry.SetTo(ref, false);
if (error == B_OK && entry.IsSymLink()) {
// ref refers to a link
error = entry.SetTo(ref, true);
if (error == B_OK)
error = entry.GetRef(ref);
if (error != B_OK)
error = B_LAUNCH_FAILED_NO_RESOLVE_LINK;
}
BEntry entry;
status_t error = entry.SetTo(ref, false);
if (error == B_OK && entry.IsSymLink()) {
// ref refers to a link
error = entry.SetTo(ref, true);
if (error == B_OK)
error = entry.GetRef(ref);
if (error != B_OK)
error = B_LAUNCH_FAILED_NO_RESOLVE_LINK;
}
// init node
BNode node;
if (error == B_OK)
@ -2095,13 +2111,14 @@ status_t
BRoster::_TranslateType(const char *mimeType, BMimeType *appMeta,
entry_ref *appRef, BFile *appFile) const
{
status_t error = (mimeType && appMeta && appRef && appFile
&& strlen(mimeType) < B_MIME_TYPE_LENGTH ? B_OK
: B_BAD_VALUE);
if (mimeType == NULL || appMeta == NULL || appRef == NULL
|| appFile == NULL || strlen(mimeType) >= B_MIME_TYPE_LENGTH)
return B_BAD_VALUE;
// create a BMimeType and check, if the type is installed
BMimeType type;
if (error == B_OK)
error = type.SetTo(mimeType);
status_t error = type.SetTo(mimeType);
// get the preferred app
char appSignature[B_MIME_TYPE_LENGTH];
if (error == B_OK) {