BRoster::Launch() eventually launches the application in question

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
This commit is contained in:
Ingo Weinhold
2006-08-31 17:54:16 +00:00
parent a847b384c6
commit 6bfd06d1ff
9 changed files with 178 additions and 67 deletions
+10 -4
View File
@@ -155,23 +155,29 @@ error reply fields:
----------------------------------------------------------------------- -----------------------------------------------------------------------
app pre-registration check (BRoster::IsAppPreRegistered()) app registration check (BRoster::IsAppRegistered())
target: roster target: roster
message: B_REG_IS_APP_PRE_REGISTERED message: B_REG_IS_APP_REGISTERED
"ref": B_REF_TYPE "ref": B_REF_TYPE
"team": B_INT32_TYPE ( "team": B_INT32_TYPE
| "token": B_INT32_TYPE )
reply: standard success reply: standard success
"registered": B_BOOL_TYPE
"pre-registered": B_BOOL_TYPE "pre-registered": B_BOOL_TYPE
[ "app_info": flattened app_info ]
on error: - B_NO_REPLY (fatal) on error: - B_NO_REPLY (fatal)
- standard error - standard error
message fields: message fields:
- "ref": An entry_ref to the application executable. - "ref": An entry_ref to the application executable.
- "team": The application team (team_id). - "team": The application team (team_id).
- "token": The application's preregistration token.
reply fields: reply fields:
- "registered": true, if the app is (pre-)registered, false otherwise.
- "pre-registered": true, if the app is pre-registered, false otherwise. - "pre-registered": true, if the app is pre-registered, false otherwise.
- "app_info": Flattened app info, if the app is known (i.e. (pre-)registered).
error reply fields: error reply fields:
- "error": - "error":
+2
View File
@@ -136,6 +136,8 @@ class BRoster {
port_id port) const; port_id port) const;
bool _IsAppPreRegistered(const entry_ref *ref, team_id team, bool _IsAppPreRegistered(const entry_ref *ref, team_id team,
app_info *info) const; 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 _RemovePreRegApp(uint32 entryToken) const;
status_t _RemoveApp(team_id team) const; status_t _RemoveApp(team_id team) const;
void _ApplicationCrashed(team_id team); void _ApplicationCrashed(team_id team);
+1 -1
View File
@@ -55,7 +55,7 @@ enum {
// roster requests // roster requests
B_REG_ADD_APP = 'rgaa', B_REG_ADD_APP = 'rgaa',
B_REG_COMPLETE_REGISTRATION = 'rgcr', B_REG_COMPLETE_REGISTRATION = 'rgcr',
B_REG_IS_APP_PRE_REGISTERED = 'rgip', B_REG_IS_APP_REGISTERED = 'rgip',
B_REG_REMOVE_PRE_REGISTERED_APP = 'rgrp', B_REG_REMOVE_PRE_REGISTERED_APP = 'rgrp',
B_REG_REMOVE_APP = 'rgra', B_REG_REMOVE_APP = 'rgra',
B_REG_SET_THREAD_AND_TEAM = 'rgtt', B_REG_SET_THREAD_AND_TEAM = 'rgtt',
+4 -3
View File
@@ -43,9 +43,10 @@ class BRoster::Private {
port_id port) const port_id port) const
{ return fRoster->_CompleteRegistration(team, thread, port); } { return fRoster->_CompleteRegistration(team, thread, port); }
bool IsAppPreRegistered(const entry_ref *ref, team_id team, status_t IsAppRegistered(const entry_ref *ref, team_id team,
app_info *info) const uint32 token, bool *preRegistered, app_info *info) const
{ return fRoster->_IsAppPreRegistered(ref, team, info); } { return fRoster->_IsAppRegistered(ref, team, token, preRegistered,
info); }
status_t RemoveApp(team_id team) const status_t RemoveApp(team_id team) const
{ return fRoster->_RemoveApp(team); } { return fRoster->_RemoveApp(team); }
+4 -2
View File
@@ -318,8 +318,10 @@ BApplication::_InitData(const char *signature, bool initGUI, status_t *_error)
bool preRegistered = false; bool preRegistered = false;
app_info appInfo; app_info appInfo;
if (fInitError == B_OK && !isRegistrar) { if (fInitError == B_OK && !isRegistrar) {
preRegistered = BRoster::Private().IsAppPreRegistered(&ref, team, if (BRoster::Private().IsAppRegistered(&ref, team, 0, &preRegistered,
&appInfo); &appInfo) != B_OK) {
preRegistered = false;
}
} }
if (preRegistered) { if (preRegistered) {
// we are pre-registered => the app info has been filled in // we are pre-registered => the app info has been filled in
+41 -13
View File
@@ -1424,10 +1424,12 @@ BRoster::_AddApplication(const char *mimeSig, const entry_ref *ref,
error = request.AddInt32("port", port); error = request.AddInt32("port", port);
if (error == B_OK) if (error == B_OK)
error = request.AddBool("full_registration", fullReg); error = request.AddBool("full_registration", fullReg);
// send the request // send the request
BMessage reply; BMessage reply;
if (error == B_OK) if (error == B_OK)
error = fMessenger.SendMessage(&request, &reply); error = fMessenger.SendMessage(&request, &reply);
// evaluate the reply // evaluate the reply
if (error == B_OK) { if (error == B_OK) {
if (reply.what == B_REG_SUCCESS) { if (reply.what == B_REG_SUCCESS) {
@@ -1442,8 +1444,11 @@ BRoster::_AddApplication(const char *mimeSig, const entry_ref *ref,
} else { } else {
if (reply.FindInt32("error", &error) != B_OK) if (reply.FindInt32("error", &error) != B_OK)
error = B_ERROR; error = B_ERROR;
// get team and token from the reply
if (otherTeam && reply.FindInt32("other_team", otherTeam) != B_OK) if (otherTeam && reply.FindInt32("other_team", otherTeam) != B_OK)
*otherTeam = -1; *otherTeam = -1;
if (pToken && reply.FindInt32("token", (int32*)pToken) != B_OK)
*pToken = 0;
} }
} }
return error; return error;
@@ -1580,46 +1585,66 @@ BRoster::_CompleteRegistration(team_id team, thread_id thread,
return error; return error;
} }
// IsAppPreRegistered // _IsAppRegistered
/*! \brief Returns whether an application is pre-registered. /*! \brief Returns whether an application is registered.
If the application is indeed pre-registered and \a info is not \c NULL, If the application is indeed pre-registered and \a info is not \c NULL,
the methods fills in the app_info structure pointed to by \a info. the methods fills in the app_info structure pointed to by \a info.
\param ref An entry_ref referring to the app's executable \param ref An entry_ref referring to the app's executable
\param team The app's team ID \param team The app's team ID. May be -1, if \a token is given.
\param token The app's pre-registration token. May be 0, if \a team is
given.
\param preRegistered: Pointer to a pre-allocated bool to be filled in
by this method, indicating whether or not the app was
pre-registered.
\param info A pointer to a pre-allocated app_info structure to be filled \param info A pointer to a pre-allocated app_info structure to be filled
in by this method (may be \c NULL) in by this method (may be \c NULL)
\return \c true, if the application is pre-registered, \c false if not. \return
- \c B_OK, if the application is registered and all requested
information could be retrieved,
- another error code, if the app is not registered or an error occurred.
*/ */
bool status_t
BRoster::_IsAppPreRegistered(const entry_ref *ref, team_id team, BRoster::_IsAppRegistered(const entry_ref *ref, team_id team,
app_info *info) const uint32 token, bool *preRegistered, app_info *info) const
{ {
status_t error = B_OK; status_t error = B_OK;
// compose the request message // compose the request message
BMessage request(B_REG_IS_APP_PRE_REGISTERED); BMessage request(B_REG_IS_APP_REGISTERED);
if (error == B_OK && ref) if (error == B_OK && ref)
error = request.AddRef("ref", ref); error = request.AddRef("ref", ref);
if (error == B_OK && team >= 0) if (error == B_OK && team >= 0)
error = request.AddInt32("team", team); error = request.AddInt32("team", team);
if (error == B_OK && token > 0)
error = request.AddInt32("token", (int32)token);
// send the request // send the request
BMessage reply; BMessage reply;
if (error == B_OK) if (error == B_OK)
error = fMessenger.SendMessage(&request, &reply); error = fMessenger.SendMessage(&request, &reply);
// evaluate the reply // evaluate the reply
bool isRegistered = false;
bool isPreRegistered = false; bool isPreRegistered = false;
if (error == B_OK) { if (error == B_OK) {
if (reply.what == B_REG_SUCCESS) { if (reply.what == B_REG_SUCCESS) {
if (reply.FindBool("pre-registered", &isPreRegistered) != B_OK) if (reply.FindBool("registered", &isRegistered) != B_OK
|| !isRegistered
|| reply.FindBool("pre-registered", &isPreRegistered) != B_OK) {
error = B_ERROR; error = B_ERROR;
if (error == B_OK && isPreRegistered && info) }
if (error == B_OK && preRegistered)
*preRegistered = isPreRegistered;
if (error == B_OK && info)
error = find_message_app_info(&reply, info); error = find_message_app_info(&reply, info);
} else if (reply.FindInt32("error", &error) != B_OK) } else if (reply.FindInt32("error", &error) != B_OK)
error = B_ERROR; error = B_ERROR;
} }
return error == B_OK && isPreRegistered;
return error;
} }
// RemovePreRegApp // RemovePreRegApp
@@ -1815,10 +1840,13 @@ BRoster::_LaunchApp(const char *mimeType, const entry_ref *ref,
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;
// get the app flags for the running application // get the app flags for the running application
if (GetRunningAppInfo(team, &appInfo) == B_OK) error = _IsAppRegistered(&appRef, team, appToken, NULL, &appInfo);
if (error == B_OK) {
otherAppFlags = appInfo.flags; otherAppFlags = appInfo.flags;
team = appInfo.team;
}
} }
DBG(OUT(" pre-register: %s (%lx)\n", strerror(error), error)); DBG(OUT(" pre-register: %s (%lx)\n", strerror(error), error));
} }
+2 -2
View File
@@ -126,8 +126,8 @@ Registrar::MessageReceived(BMessage *message)
case B_REG_COMPLETE_REGISTRATION: case B_REG_COMPLETE_REGISTRATION:
fRoster->HandleCompleteRegistration(message); fRoster->HandleCompleteRegistration(message);
break; break;
case B_REG_IS_APP_PRE_REGISTERED: case B_REG_IS_APP_REGISTERED:
fRoster->HandleIsAppPreRegistered(message); fRoster->HandleIsAppRegistered(message);
break; break;
case B_REG_REMOVE_PRE_REGISTERED_APP: case B_REG_REMOVE_PRE_REGISTERED_APP:
fRoster->HandleRemovePreRegApp(message); fRoster->HandleRemovePreRegApp(message);
+104 -32
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2005, Ingo Weinhold, [email protected]. * Copyright 2001-2006, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -65,9 +65,8 @@ static bool larger_index(const recent_entry *entry1, const recent_entry *entry2)
are one or more instances of the application that are pre-registered, but are one or more instances of the application that are pre-registered, but
have no team ID assigned yet, the reply to the request has to be have no team ID assigned yet, the reply to the request has to be
postponed until the status of the requesting team is clear. The request postponed until the status of the requesting team is clear. The request
message is dequeued from the registrar's message queue and, with message is dequeued from the registrar's message queue and added to
additional information (IAPRRequest), added to \a fIAPRRequests for a \a fIARRequestsByID for a later reply.
later reply.
The field \a fActiveApp identifies the currently active application The field \a fActiveApp identifies the currently active application
and \a fLastToken is a counter used to generate unique tokens for and \a fLastToken is a counter used to generate unique tokens for
@@ -115,7 +114,8 @@ TRoster::TRoster()
: fLock("roster"), : fLock("roster"),
fRegisteredApps(), fRegisteredApps(),
fEarlyPreRegisteredApps(), fEarlyPreRegisteredApps(),
fIAPRRequests(), fIARRequestsByID(),
fIARRequestsByToken(),
fActiveApp(NULL), fActiveApp(NULL),
fWatchingService(), fWatchingService(),
fRecentApps(), fRecentApps(),
@@ -176,6 +176,8 @@ PRINT(("full registration: %d\n", fullReg));
// check the parameters // check the parameters
team_id otherTeam = -1; team_id otherTeam = -1;
uint32 token = 0;
uint32 launchFlags = flags & B_LAUNCH_MASK; uint32 launchFlags = flags & B_LAUNCH_MASK;
// entry_ref // entry_ref
@@ -206,6 +208,7 @@ PRINT(("ref: %ld, %lld, %s\n", ref.device, ref.directory, ref.name));
|| ((info = fEarlyPreRegisteredApps.InfoFor(signature))))) { || ((info = fEarlyPreRegisteredApps.InfoFor(signature))))) {
SET_ERROR(error, B_ALREADY_RUNNING); SET_ERROR(error, B_ALREADY_RUNNING);
otherTeam = info->team; otherTeam = info->team;
token = info->token;
} }
} }
@@ -219,7 +222,6 @@ PRINT(("ref: %ld, %lld, %s\n", ref.device, ref.directory, ref.name));
} }
// Add the application info. // Add the application info.
uint32 token = 0;
if (error == B_OK) { if (error == B_OK) {
// alloc and init the info // alloc and init the info
RosterAppInfo *info = new(nothrow) RosterAppInfo; RosterAppInfo *info = new(nothrow) RosterAppInfo;
@@ -270,6 +272,8 @@ PRINT(("added to early pre-regs, token: %lu\n", token));
reply.AddInt32("error", error); reply.AddInt32("error", error);
if (otherTeam >= 0) if (otherTeam >= 0)
reply.AddInt32("other_team", otherTeam); reply.AddInt32("other_team", otherTeam);
if (token > 0)
reply.AddInt32("token", (int32)token);
request->SendReply(&reply); request->SendReply(&reply);
} }
@@ -339,12 +343,12 @@ TRoster::HandleCompleteRegistration(BMessage *request)
FUNCTION_END(); FUNCTION_END();
} }
// HandleIsAppPreRegistered // HandleIsAppRegistered
/*! \brief Handles an IsAppPreRegistered() request. /*! \brief Handles an IsAppRegistered() request.
\param request The request message \param request The request message
*/ */
void void
TRoster::HandleIsAppPreRegistered(BMessage *request) TRoster::HandleIsAppRegistered(BMessage *request)
{ {
FUNCTION_START(); FUNCTION_START();
@@ -354,36 +358,48 @@ TRoster::HandleIsAppPreRegistered(BMessage *request)
// get the parameters // get the parameters
entry_ref ref; entry_ref ref;
team_id team; team_id team;
uint32 token;
if (request->FindRef("ref", &ref) != B_OK) if (request->FindRef("ref", &ref) != B_OK)
SET_ERROR(error, B_BAD_VALUE); SET_ERROR(error, B_BAD_VALUE);
if (request->FindInt32("team", &team) != B_OK) if (request->FindInt32("team", &team) != B_OK)
team = -1; team = -1;
PRINT(("team: %ld\n", team)); if (request->FindInt32("token", (int32*)&token) != B_OK)
token = 0;
PRINT(("team: %ld, token: %lu\n", team, token));
PRINT(("ref: %ld, %lld, %s\n", ref.device, ref.directory, ref.name)); PRINT(("ref: %ld, %lld, %s\n", ref.device, ref.directory, ref.name));
// check the parameters // check the parameters
// entry_ref // entry_ref
if (error == B_OK & !BEntry(&ref).Exists()) if (error == B_OK & !BEntry(&ref).Exists())
SET_ERROR(error, B_ENTRY_NOT_FOUND); SET_ERROR(error, B_ENTRY_NOT_FOUND);
// team // team/token
if (error == B_OK && team < 0) if (error == B_OK && team < 0 && token == 0)
SET_ERROR(error, B_BAD_VALUE); SET_ERROR(error, B_BAD_VALUE);
// look up the information // look up the information
RosterAppInfo *info = NULL; RosterAppInfo *info = NULL;
if (error == B_OK) { if (error == B_OK) {
if ((info = fRegisteredApps.InfoFor(team)) != NULL) { if ((info = fRegisteredApps.InfoFor(team)) != NULL) {
PRINT(("found team in fRegisteredApps\n")); PRINT(("found team in fRegisteredApps\n"));
_ReplyToIAPRRequest(request, info); _ReplyToIARRequest(request, info);
} else if ((info = fEarlyPreRegisteredApps.InfoFor(&ref)) != NULL) { } else if (token > 0
PRINT(("found ref in fEarlyRegisteredApps\n")); && (info = fEarlyPreRegisteredApps.InfoForToken(token)) != NULL) {
PRINT(("found ref in fEarlyRegisteredApps (by token)\n"));
// pre-registered and has no team ID assigned yet -- queue the // pre-registered and has no team ID assigned yet -- queue the
// request // request
be_app->DetachCurrentMessage(); be_app->DetachCurrentMessage();
IAPRRequest queuedRequest = { ref, team, request }; _AddIARRequest(fIARRequestsByToken, team, request);
fIAPRRequests[team] = queuedRequest; } else if (team >= 0
&& (info = fEarlyPreRegisteredApps.InfoFor(&ref)) != NULL) {
PRINT(("found ref in fEarlyRegisteredApps (by ref)\n"));
// pre-registered and has no team ID assigned yet -- queue the
// request
be_app->DetachCurrentMessage();
_AddIARRequest(fIARRequestsByID, team, request);
} else { } else {
PRINT(("didn't find team or ref\n")); PRINT(("didn't find team or ref\n"));
// team not registered, ref not early pre-registered // team not registered, ref/token not early pre-registered
_ReplyToIAPRRequest(request, NULL); _ReplyToIARRequest(request, NULL);
} }
} else { } else {
// reply to the request on error // reply to the request on error
@@ -524,14 +540,23 @@ PRINT(("team: %ld, thread: %ld, token: %lu\n", team, thread, token));
delete_port(info->port); delete_port(info->port);
delete info; delete info;
} }
// handle a pending IsAppPreRegistered() request // handle pending IsAppRegistered() requests
IAPRRequestMap::iterator it = fIAPRRequests.find(team); IARRequestMap::iterator it = fIARRequestsByID.find(team);
if (it != fIAPRRequests.end()) { if (it != fIARRequestsByID.end()) {
IAPRRequest &request = it->second; BMessageQueue *requests = it->second;
if (error == B_OK) if (error == B_OK)
_ReplyToIAPRRequest(request.request, info); _ReplyToIARRequests(requests, info);
delete request.request; delete requests;
fIAPRRequests.erase(it); fIARRequestsByID.erase(it);
}
it = fIARRequestsByToken.find((int32)token);
if (it != fIARRequestsByToken.end()) {
BMessageQueue *requests = it->second;
if (error == B_OK)
_ReplyToIARRequests(requests, info);
delete requests;
fIARRequestsByToken.erase(it);
} }
} else } else
SET_ERROR(error, B_REG_APP_NOT_PRE_REGISTERED); SET_ERROR(error, B_REG_APP_NOT_PRE_REGISTERED);
@@ -1543,11 +1568,57 @@ TRoster::_NextToken()
return ++fLastToken; return ++fLastToken;
} }
// _ReplyToIAPRRequest // _AddIARRequest
/*! \brief Sends a reply message to a IsAppPreRegistered() request. /*! \brief Adds an IsAppRegistered() request to the given map.
If something goes wrong, the method deletes the request.
\param map The map the request shall be added to.
\param key The key under which to add the request.
\param request The request message to be added.
*/
void
TRoster::_AddIARRequest(IARRequestMap& map, int32 key, BMessage* request)
{
IARRequestMap::iterator it = map.find(key);
BMessageQueue* requests = NULL;
if (it == map.end()) {
requests = new(nothrow) BMessageQueue();
if (!requests) {
delete request;
return;
}
map[key] = requests;
} else
requests = it->second;
requests->AddMessage(request);
}
// _ReplyToIARRequests
/*! \brief Invokes _ReplyToIARRequest() for all messages in the given
message queue.
\param requests The request messages to be replied to
\param info The RosterAppInfo of the application in question
(may be \c NULL)
*/
void
TRoster::_ReplyToIARRequests(BMessageQueue *requests,
const RosterAppInfo *info)
{
while (BMessage* request = requests->NextMessage()) {
_ReplyToIARRequest(request, info);
delete request;
}
}
// _ReplyToIARRequest
/*! \brief Sends a reply message to an IsAppRegistered() request.
The message to be sent is a simple \c B_REG_SUCCESS message containing The message to be sent is a simple \c B_REG_SUCCESS message containing
a "pre-registered" field, that sais whether or not the application is a "pre-registered" field, that says whether or not the application is
pre-registered. It will be set to \c false, unless an \a info is supplied pre-registered. It will be set to \c false, unless an \a info is supplied
and the application this info refers to is pre-registered. and the application this info refers to is pre-registered.
@@ -1556,7 +1627,7 @@ TRoster::_NextToken()
(may be \c NULL) (may be \c NULL)
*/ */
void void
TRoster::_ReplyToIAPRRequest(BMessage *request, const RosterAppInfo *info) TRoster::_ReplyToIARRequest(BMessage *request, const RosterAppInfo *info)
{ {
// pre-registered or registered? // pre-registered or registered?
bool preRegistered = false; bool preRegistered = false;
@@ -1573,9 +1644,10 @@ TRoster::_ReplyToIAPRRequest(BMessage *request, const RosterAppInfo *info)
} }
// send reply // send reply
BMessage reply(B_REG_SUCCESS); BMessage reply(B_REG_SUCCESS);
reply.AddBool("registered", (bool)info);
reply.AddBool("pre-registered", preRegistered); reply.AddBool("pre-registered", preRegistered);
PRINT(("_ReplyToIAPRRequest(): pre-registered: %d\n", preRegistered)); PRINT(("_ReplyToIARRequest(): pre-registered: %d\n", preRegistered));
if (preRegistered) if (info)
_AddMessageAppInfo(&reply, info); _AddMessageAppInfo(&reply, info);
request->SendReply(&reply); request->SendReply(&reply);
} }
+10 -10
View File
@@ -32,6 +32,7 @@
#include <map> #include <map>
#include <Locker.h> #include <Locker.h>
#include <MessageQueue.h>
#include <SupportDefs.h> #include <SupportDefs.h>
#include "AppInfoList.h" #include "AppInfoList.h"
@@ -48,13 +49,7 @@ using std::map;
class BMessage; class BMessage;
class WatchingService; class WatchingService;
struct IAPRRequest { typedef map<int32, BMessageQueue*> IARRequestMap;
entry_ref ref;
team_id team;
BMessage *request;
};
typedef map<team_id, IAPRRequest> IAPRRequestMap;
class TRoster { class TRoster {
public: public:
@@ -63,7 +58,7 @@ public:
void HandleAddApplication(BMessage *request); void HandleAddApplication(BMessage *request);
void HandleCompleteRegistration(BMessage *request); void HandleCompleteRegistration(BMessage *request);
void HandleIsAppPreRegistered(BMessage *request); void HandleIsAppRegistered(BMessage *request);
void HandleRemovePreRegApp(BMessage *request); void HandleRemovePreRegApp(BMessage *request);
void HandleRemoveApp(BMessage *request); void HandleRemoveApp(BMessage *request);
void HandleSetThreadAndTeam(BMessage *request); void HandleSetThreadAndTeam(BMessage *request);
@@ -115,7 +110,11 @@ private:
static status_t _AddMessageWatchingInfo(BMessage *message, static status_t _AddMessageWatchingInfo(BMessage *message,
const app_info *info); const app_info *info);
uint32 _NextToken(); uint32 _NextToken();
void _ReplyToIAPRRequest(BMessage *request, const RosterAppInfo *info);
void _AddIARRequest(IARRequestMap& map, int32 key, BMessage* request);
void _ReplyToIARRequests(BMessageQueue *requests,
const RosterAppInfo *info);
void _ReplyToIARRequest(BMessage *request, const RosterAppInfo *info);
void _HandleGetRecentEntries(BMessage *request); void _HandleGetRecentEntries(BMessage *request);
@@ -129,7 +128,8 @@ private:
BLocker fLock; BLocker fLock;
AppInfoList fRegisteredApps; AppInfoList fRegisteredApps;
AppInfoList fEarlyPreRegisteredApps; AppInfoList fEarlyPreRegisteredApps;
IAPRRequestMap fIAPRRequests; IARRequestMap fIARRequestsByID;
IARRequestMap fIARRequestsByToken;
RosterAppInfo *fActiveApp; RosterAppInfo *fActiveApp;
WatchingService fWatchingService; WatchingService fWatchingService;
RecentApps fRecentApps; RecentApps fRecentApps;