6bfd06d1ff
in several steps: 1. early pre-registration with the registrar ("I wanna launch the app, make sure noone interferes.") 2. load the app image 3. finish pre-registration with the registrar ("I have launched the app, here is its team ID.") 4. start app main thread 5. send "on launch" messages to the app (argv, refs, others) If the app is already running or being launched, 1. fails with a conclusive error code and returns the team ID and the pre-registration token of the app. Steps 2 - 4 are skipped and only the messages are delivered using the team ID returned by 1. This change fixes a race condition: The failed early pre-registration request obviously cannot return the team ID, if the other thread launching the app has not finished step 3 yet. Thus the argv/refs message would not get delivered and Launch() would not return the correct team ID. Now we wait for the pre-registration to be finished in this case, using the former _IsAppPreRegistered() mechanism, which already provided such a waiting feature for one request. It has been extended to accomodate an arbitrary number of waiting requests and renamed to _IsAppRegistered(). This fixed bug #763. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18728 a95241bf-73f2-0310-859d-f6bbb57e9c96
182 lines
5.6 KiB
C++
182 lines
5.6 KiB
C++
/*
|
|
* Copyright 2001-2006, Haiku.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Ingo Weinhold (bonefish@users.sf.net)
|
|
*/
|
|
#ifndef _ROSTER_H
|
|
#define _ROSTER_H
|
|
|
|
|
|
#include <Entry.h>
|
|
#include <Messenger.h>
|
|
#include <OS.h>
|
|
|
|
|
|
struct app_info {
|
|
app_info();
|
|
~app_info();
|
|
|
|
thread_id thread;
|
|
team_id team;
|
|
port_id port;
|
|
uint32 flags;
|
|
entry_ref ref;
|
|
char signature[B_MIME_TYPE_LENGTH];
|
|
};
|
|
|
|
// app flags
|
|
#define B_SINGLE_LAUNCH (0x0)
|
|
#define B_MULTIPLE_LAUNCH (0x1)
|
|
#define B_EXCLUSIVE_LAUNCH (0x2)
|
|
#define B_LAUNCH_MASK (0x3)
|
|
#define B_BACKGROUND_APP (0x4)
|
|
#define B_ARGV_ONLY (0x8)
|
|
#define _B_APP_INFO_RESERVED1_ (0x10000000)
|
|
|
|
// watching request flags
|
|
enum {
|
|
B_REQUEST_LAUNCHED = 0x00000001,
|
|
B_REQUEST_QUIT = 0x00000002,
|
|
B_REQUEST_ACTIVATED = 0x00000004,
|
|
};
|
|
|
|
// notification message "what"
|
|
enum {
|
|
B_SOME_APP_LAUNCHED = 'BRAS',
|
|
B_SOME_APP_QUIT = 'BRAQ',
|
|
B_SOME_APP_ACTIVATED = 'BRAW',
|
|
};
|
|
|
|
class BList;
|
|
|
|
|
|
class BRoster {
|
|
public:
|
|
BRoster();
|
|
~BRoster();
|
|
|
|
// running apps
|
|
bool IsRunning(const char *mimeSig) const;
|
|
bool IsRunning(entry_ref *ref) const;
|
|
team_id TeamFor(const char *mimeSig) const;
|
|
team_id TeamFor(entry_ref *ref) const;
|
|
void GetAppList(BList *teamIDList) const;
|
|
void GetAppList(const char *sig, BList *teamIDList) const;
|
|
|
|
// app infos
|
|
status_t GetAppInfo(const char *sig, app_info *info) const;
|
|
status_t GetAppInfo(entry_ref *ref, app_info *info) const;
|
|
status_t GetRunningAppInfo(team_id team, app_info *info) const;
|
|
status_t GetActiveAppInfo(app_info *info) const;
|
|
|
|
// find app
|
|
status_t FindApp(const char *mimeType, entry_ref *app) const;
|
|
status_t FindApp(entry_ref *ref, entry_ref *app) const;
|
|
|
|
// broadcast
|
|
status_t Broadcast(BMessage *message) const;
|
|
status_t Broadcast(BMessage *message, BMessenger replyTo) const;
|
|
|
|
// watching
|
|
status_t StartWatching(BMessenger target,
|
|
uint32 eventMask = B_REQUEST_LAUNCHED | B_REQUEST_QUIT) const;
|
|
status_t StopWatching(BMessenger target) const;
|
|
|
|
status_t ActivateApp(team_id team) const;
|
|
|
|
// launch app
|
|
status_t Launch(const char *mimeType, BMessage *initialMessage = 0,
|
|
team_id *appTeam = 0) const;
|
|
status_t Launch(const char *mimeType, BList *messageList,
|
|
team_id *appTeam = 0) const;
|
|
status_t Launch(const char *mimeType, int argc, char **args,
|
|
team_id *appTeam = 0) const;
|
|
status_t Launch(const entry_ref *ref, const BMessage *initialMessage = 0,
|
|
team_id *appTeam = 0) const;
|
|
status_t Launch(const entry_ref *ref, const BList *messageList,
|
|
team_id *appTeam = 0) const;
|
|
status_t Launch(const entry_ref *ref, int argc, const char * const *args,
|
|
team_id *appTeam = 0) const;
|
|
|
|
// recent documents, folders, apps
|
|
void GetRecentDocuments(BMessage *refList, int32 maxCount,
|
|
const char *fileType = 0,
|
|
const char *appSig = 0) const;
|
|
void GetRecentDocuments(BMessage *refList, int32 maxCount,
|
|
const char *fileTypes[], int32 fileTypesCount,
|
|
const char *appSig = 0) const;
|
|
void GetRecentFolders(BMessage *refList, int32 maxCount,
|
|
const char *appSig = 0) const;
|
|
void GetRecentApps(BMessage *refList, int32 maxCount) const;
|
|
void AddToRecentDocuments(const entry_ref *doc,
|
|
const char *appSig = 0) const;
|
|
void AddToRecentFolders(const entry_ref *folder,
|
|
const char *appSig = 0) const;
|
|
|
|
// private/reserved stuff starts here
|
|
class Private;
|
|
|
|
private:
|
|
class ArgVector;
|
|
friend class Private;
|
|
|
|
status_t _ShutDown(bool reboot, bool confirm, bool synchronous);
|
|
|
|
status_t _AddApplication(const char *mimeSig, const entry_ref *ref,
|
|
uint32 flags, team_id team, thread_id thread,
|
|
port_id port, bool fullReg, uint32 *pToken,
|
|
team_id *otherTeam) const;
|
|
status_t _SetSignature(team_id team, const char *mimeSig) const;
|
|
void _SetThread(team_id team, thread_id thread) const;
|
|
status_t _SetThreadAndTeam(uint32 entryToken, thread_id thread,
|
|
team_id team) const;
|
|
status_t _CompleteRegistration(team_id team, thread_id thread,
|
|
port_id port) const;
|
|
bool _IsAppPreRegistered(const entry_ref *ref, team_id team,
|
|
app_info *info) const;
|
|
status_t _IsAppRegistered(const entry_ref *ref, team_id team,
|
|
uint32 token, bool *preRegistered, app_info *info) const;
|
|
status_t _RemovePreRegApp(uint32 entryToken) const;
|
|
status_t _RemoveApp(team_id team) const;
|
|
void _ApplicationCrashed(team_id team);
|
|
|
|
status_t _LaunchApp(const char *mimeType, const entry_ref *ref,
|
|
const BList *messageList, int argc,
|
|
const char *const *args,
|
|
team_id *appTeam) const;
|
|
bool _UpdateActiveApp(team_id team) const;
|
|
void _SetAppFlags(team_id team, uint32 flags) const;
|
|
void _DumpRoster() const;
|
|
status_t _ResolveApp(const char *inType, entry_ref *ref, entry_ref *appRef,
|
|
char *appSig, uint32 *appFlags,
|
|
bool *wasDocument) const;
|
|
status_t _TranslateRef(entry_ref *ref, BMimeType *appMeta,
|
|
entry_ref *appRef, BFile *appFile,
|
|
bool *wasDocument) const;
|
|
status_t _TranslateType(const char *mimeType, BMimeType *appMeta,
|
|
entry_ref *appRef, BFile *appFile) const;
|
|
status_t _SniffFile(const entry_ref *file, BNodeInfo *nodeInfo,
|
|
char *mimeType) const;
|
|
status_t _SendToRunning(team_id team, int argc, const char *const *args,
|
|
const BList *messageList, const entry_ref *ref,
|
|
bool readyToRun) const;
|
|
void _InitMessengers();
|
|
void _AddToRecentApps(const char *appSig) const;
|
|
void _ClearRecentDocuments() const;
|
|
void _ClearRecentFolders() const;
|
|
void _ClearRecentApps() const;
|
|
void _LoadRecentLists(const char *filename) const;
|
|
void _SaveRecentLists(const char *filename) const;
|
|
|
|
BMessenger fMessenger;
|
|
BMessenger fMimeMessenger;
|
|
uint32 _reserved[3];
|
|
};
|
|
|
|
// global BRoster instance
|
|
extern const BRoster *be_roster;
|
|
|
|
#endif // _ROSTER_H
|