зеркало из https://github.com/mozilla/gecko-dev.git
implement QueryClientByName
This commit is contained in:
Родитель
9b6ae7fdf7
Коммит
a8e727269b
|
@ -59,7 +59,6 @@ enum {
|
|||
IPCM_MSG_TYPE_CLIENT_DEL_TARGET,
|
||||
IPCM_MSG_TYPE_QUERY_CLIENT_BY_NAME,
|
||||
IPCM_MSG_TYPE_QUERY_CLIENT_INFO,
|
||||
IPCM_MSG_TYPE_QUERY_FAILED,
|
||||
IPCM_MSG_TYPE_FORWARD,
|
||||
IPCM_MSG_TYPE_UNKNOWN // unknown message type
|
||||
};
|
||||
|
@ -125,6 +124,10 @@ public:
|
|||
PRUint32 Reason() const { return Second(); }
|
||||
};
|
||||
|
||||
enum {
|
||||
IPCM_ERROR_CLIENT_NOT_FOUND = 1
|
||||
};
|
||||
|
||||
//
|
||||
// IPCM_MSG_TYPE_CLIENT_HELLO
|
||||
//
|
||||
|
|
|
@ -56,14 +56,14 @@ public:
|
|||
// message handlers
|
||||
//
|
||||
|
||||
void handlePing(ipcClient *client, const ipcMessage *rawMsg)
|
||||
void OnPing(ipcClient *client, const ipcMessage *rawMsg)
|
||||
{
|
||||
LOG(("got PING\n"));
|
||||
|
||||
IPC_SendMsg(client, new ipcmMessagePing());
|
||||
}
|
||||
|
||||
void handleClientHello(ipcClient *client, const ipcMessage *rawMsg)
|
||||
void OnClientHello(ipcClient *client, const ipcMessage *rawMsg)
|
||||
{
|
||||
LOG(("got CLIENT_HELLO\n"));
|
||||
|
||||
|
@ -75,7 +75,23 @@ public:
|
|||
IPC_SendMsg(client, new ipcmMessageClientID(client->ID()));
|
||||
}
|
||||
|
||||
void handleForward(ipcClient *client, const ipcMessage *rawMsg)
|
||||
void OnQueryClientByName(ipcClient *client, const ipcMessage *rawMsg)
|
||||
{
|
||||
LOG(("got QUERY_CLIENT_BY_NAME\n"));
|
||||
|
||||
ipcMessageCast<ipcmMessageQueryClientByName> msg(rawMsg);
|
||||
ipcClient *result = IPC_GetClientByName(msg->Name());
|
||||
if (result) {
|
||||
LOG((" client exists w/ ID = %u\n", result->ID()));
|
||||
IPC_SendMsg(client, new ipcmMessageClientID(result->ID()));
|
||||
}
|
||||
else {
|
||||
LOG((" client does not exist\n"));
|
||||
IPC_SendMsg(client, new ipcmMessageError(IPCM_ERROR_CLIENT_NOT_FOUND));
|
||||
}
|
||||
}
|
||||
|
||||
void OnForward(ipcClient *client, const ipcMessage *rawMsg)
|
||||
{
|
||||
LOG(("got FORWARD\n"));
|
||||
|
||||
|
@ -106,19 +122,19 @@ public:
|
|||
{
|
||||
static MsgHandler handlers[] =
|
||||
{
|
||||
&ipcCommandModule::handlePing,
|
||||
&ipcCommandModule::OnPing,
|
||||
NULL, // ERROR
|
||||
&ipcCommandModule::handleClientHello,
|
||||
&ipcCommandModule::OnClientHello,
|
||||
NULL, // CLIENT_ID
|
||||
NULL, // CLIENT_INFO
|
||||
NULL, // CLIENT_ADD_NAME
|
||||
NULL, // CLIENT_DEL_NAME
|
||||
NULL, // CLIENT_ADD_TARGET
|
||||
NULL, // CLIENT_DEL_TARGET
|
||||
NULL, // QUERY_CLIENT_BY_NAME
|
||||
&ipcCommandModule::OnQueryClientByName,
|
||||
NULL, // QUERY_CLIENT_INFO
|
||||
NULL, // QUERY_FAILED
|
||||
&ipcCommandModule::handleForward,
|
||||
&ipcCommandModule::OnForward,
|
||||
};
|
||||
|
||||
int type = IPCM_GetMsgType(rawMsg);
|
||||
|
|
|
@ -44,8 +44,13 @@
|
|||
#include "ipcConfig.h"
|
||||
#include "ipcLog.h"
|
||||
#include "ipcService.h"
|
||||
#include "ipcMessageUtils.h"
|
||||
#include "ipcm.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static PRBool PR_CALLBACK
|
||||
ipcReleaseMessageObserver(nsHashKey *aKey, void *aData, void* aClosure)
|
||||
{
|
||||
|
@ -54,10 +59,44 @@ ipcReleaseMessageObserver(nsHashKey *aKey, void *aData, void* aClosure)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ipcClientInfo
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ipcClientInfo, ipcIClientInfo)
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcClientInfo::GetID(PRUint32 *aID)
|
||||
{
|
||||
*aID = mID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcClientInfo::GetName(nsACString &aName)
|
||||
{
|
||||
aName = mName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcClientInfo::GetAliases(nsISimpleEnumerator **aliases)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ipcClientInfo::GetTargets(nsISimpleEnumerator **targets)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ipcService
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
PRUint32 ipcService::gLastReqToken = 0;
|
||||
|
||||
ipcService::ipcService()
|
||||
: mTransport(nsnull)
|
||||
, mClientID(0)
|
||||
|
@ -114,6 +153,39 @@ ipcService::Init()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ipcService::HandleQueryResult(const ipcMessage *rawMsg, PRBool succeeded)
|
||||
{
|
||||
ipcClientQuery *query = mQueryQ.First();
|
||||
if (!query) {
|
||||
NS_ERROR("no pending query; ignoring message.");
|
||||
return;
|
||||
}
|
||||
|
||||
PRUint32 cStatus;
|
||||
ipcClientInfo *info;
|
||||
|
||||
if (succeeded) {
|
||||
cStatus = ipcIClientObserver::CLIENT_UP;
|
||||
|
||||
ipcMessageCast<ipcmMessageClientID> msg(rawMsg);
|
||||
info = new ipcClientInfo();
|
||||
if (info) {
|
||||
NS_ADDREF(info);
|
||||
info->Init(msg->ClientID(), query->mName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
cStatus = ipcIClientObserver::CLIENT_DOWN;
|
||||
info = nsnull;
|
||||
}
|
||||
|
||||
query->mObserver->OnClientStatus(query->mReqToken, info, cStatus);
|
||||
|
||||
NS_IF_RELEASE(info);
|
||||
mQueryQ.DeleteFirst();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// interface impl
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -164,6 +236,11 @@ ipcService::QueryClientByName(const nsACString &name,
|
|||
//
|
||||
// now queue up the observer and generate a token.
|
||||
//
|
||||
ipcClientQuery *query = new ipcClientQuery();
|
||||
query->mName = name;
|
||||
query->mReqToken = *token = ++gLastReqToken;
|
||||
query->mObserver = observer;
|
||||
mQueryQ.Append(query);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -240,17 +317,35 @@ ipcService::OnConnectionEstablished(PRUint32 clientID)
|
|||
void
|
||||
ipcService::OnConnectionLost()
|
||||
{
|
||||
//
|
||||
// XXX error out any pending queries
|
||||
//
|
||||
|
||||
mClientID = 0;
|
||||
}
|
||||
|
||||
void
|
||||
ipcService::OnMessageAvailable(const ipcMessage *msg)
|
||||
{
|
||||
nsIDKey key(msg->Target());
|
||||
|
||||
ipcIMessageObserver *observer = (ipcIMessageObserver *) mObserverDB.Get(&key);
|
||||
if (observer)
|
||||
observer->OnMessageAvailable(msg->Target(),
|
||||
msg->Data(),
|
||||
msg->DataLen());
|
||||
if (msg->Target().Equals(IPCM_TARGET)) {
|
||||
//
|
||||
// all IPCM messages stop here.
|
||||
//
|
||||
switch (IPCM_GetMsgType(msg)) {
|
||||
case IPCM_MSG_TYPE_CLIENT_ID:
|
||||
HandleQueryResult(msg, PR_TRUE);
|
||||
break;
|
||||
case IPCM_MSG_TYPE_ERROR:
|
||||
HandleQueryResult(msg, PR_FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nsIDKey key(msg->Target());
|
||||
ipcIMessageObserver *observer = (ipcIMessageObserver *) mObserverDB.Get(&key);
|
||||
if (observer)
|
||||
observer->OnMessageAvailable(msg->Target(),
|
||||
msg->Data(),
|
||||
msg->DataLen());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,11 +48,34 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsHashtable.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ipcClientInfo
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class ipcClientInfo : public ipcIClientInfo
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IPCICLIENTINFO
|
||||
|
||||
ipcClientInfo() : mID(0) { NS_INIT_ISUPPORTS(); }
|
||||
virtual ~ipcClientInfo() {}
|
||||
|
||||
void Init(PRUint32 cID, const nsACString &cName)
|
||||
{
|
||||
mID = cID;
|
||||
mName = cName;
|
||||
}
|
||||
|
||||
private:
|
||||
PRUint32 mID;
|
||||
nsCString mName;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ipcClientQuery
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
class ipcClientQuery
|
||||
{
|
||||
public:
|
||||
|
@ -62,10 +85,12 @@ public:
|
|||
{ }
|
||||
|
||||
ipcClientQuery *mNext;
|
||||
nsCString mName;
|
||||
PRUint32 mReqToken;
|
||||
nsCOMPtr<ipcIClientObserver> mObserver;
|
||||
};
|
||||
*/
|
||||
|
||||
typedef ipcQueue<ipcClientQuery> ipcClientQueryQ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ipcService
|
||||
|
@ -84,16 +109,21 @@ public:
|
|||
nsresult Init();
|
||||
|
||||
private:
|
||||
nsresult ErrorAccordingToIPCM(PRUint32 err);
|
||||
void HandleQueryResult(const ipcMessage *, PRBool succeeded);
|
||||
|
||||
// ipcTransportObserver:
|
||||
void OnConnectionEstablished(PRUint32 clientID);
|
||||
void OnConnectionLost();
|
||||
void OnMessageAvailable(const ipcMessage *);
|
||||
|
||||
static PRUint32 gLastReqToken;
|
||||
|
||||
nsHashtable mObserverDB;
|
||||
ipcTransport *mTransport;
|
||||
PRUint32 mClientID;
|
||||
|
||||
//ipcClientQuery *mQueryQ;
|
||||
ipcClientQueryQ mQueryQ;
|
||||
};
|
||||
|
||||
#endif // !ipcService_h__
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#include "nsIEventQueueService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIComponentRegistrar.h"
|
||||
#include "nsLiteralString.h"
|
||||
#include "nsString.h"
|
||||
|
||||
static const nsID TestTargetID =
|
||||
{ /* e628fc6e-a6a7-48c7-adba-f241d1128fb8 */
|
||||
|
@ -64,16 +64,15 @@ static nsIEventQueue* gEventQ = nsnull;
|
|||
static PRBool gKeepRunning = PR_TRUE;
|
||||
//static PRInt32 gMsgCount = 0;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class myIpcMessageObserver : public ipcIMessageObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IPCIMESSAGEOBSERVER
|
||||
|
||||
myIpcMessageObserver()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
myIpcMessageObserver() { NS_INIT_ISUPPORTS(); }
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(myIpcMessageObserver, ipcIMessageObserver)
|
||||
|
@ -89,6 +88,38 @@ myIpcMessageObserver::OnMessageAvailable(const nsID &target, const char *data, P
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class myIpcClientObserver : public ipcIClientObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IPCICLIENTOBSERVER
|
||||
|
||||
myIpcClientObserver() { NS_INIT_ISUPPORTS(); }
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(myIpcClientObserver, ipcIClientObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
myIpcClientObserver::OnClientStatus(PRUint32 aReqToken, ipcIClientInfo *aClientInfo, PRUint32 aStatus)
|
||||
{
|
||||
printf("*** got client status [token=%u info=%p status=%u]\n", aReqToken, (void *) aClientInfo, aStatus);
|
||||
|
||||
if (aClientInfo) {
|
||||
PRUint32 cID;
|
||||
if (NS_SUCCEEDED(aClientInfo->GetID(&cID))) {
|
||||
nsCAutoString cName;
|
||||
if (NS_SUCCEEDED(aClientInfo->GetName(cName)))
|
||||
printf("*** name:%s --> ID:%u\n", cName.get(), cID);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SendMsg(ipcIService *ipc, const nsID &target, const char *data, PRUint32 dataLen)
|
||||
{
|
||||
printf("*** sending message: [dataLen=%u]\n", dataLen);
|
||||
|
@ -199,6 +230,10 @@ int main(int argc, char **argv)
|
|||
"60 this is a really long message.\n";
|
||||
SendMsg(ipcServ, TestTargetID, data, strlen(data)+1);
|
||||
|
||||
PRUint32 reqToken;
|
||||
nsCOMPtr<ipcIClientObserver> obs(new myIpcClientObserver());
|
||||
ipcServ->QueryClientByName(NS_LITERAL_CSTRING("foopy"), obs, &reqToken);
|
||||
|
||||
while (gKeepRunning)
|
||||
gEventQ->ProcessPendingEvents();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче