From a8e727269bf5b6492519775abc18a1ac7fe5e2b1 Mon Sep 17 00:00:00 2001 From: "darin%netscape.com" Date: Sat, 2 Nov 2002 18:57:15 +0000 Subject: [PATCH] implement QueryClientByName --- modules/ipc/common/ipcm.h | 5 +- modules/ipc/daemon/ipcCommandModule.cpp | 30 +++++-- modules/ipc/src/ipcService.cpp | 109 ++++++++++++++++++++++-- modules/ipc/src/ipcService.h | 36 +++++++- modules/ipc/test/TestIPC.cpp | 45 ++++++++-- 5 files changed, 202 insertions(+), 23 deletions(-) diff --git a/modules/ipc/common/ipcm.h b/modules/ipc/common/ipcm.h index 979c4860be3a..9add17a028df 100644 --- a/modules/ipc/common/ipcm.h +++ b/modules/ipc/common/ipcm.h @@ -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 // diff --git a/modules/ipc/daemon/ipcCommandModule.cpp b/modules/ipc/daemon/ipcCommandModule.cpp index 8f8eea35a74e..5b8cb14e78e4 100644 --- a/modules/ipc/daemon/ipcCommandModule.cpp +++ b/modules/ipc/daemon/ipcCommandModule.cpp @@ -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 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); diff --git a/modules/ipc/src/ipcService.cpp b/modules/ipc/src/ipcService.cpp index 047e0cd588b0..4c61a53855ac 100644 --- a/modules/ipc/src/ipcService.cpp +++ b/modules/ipc/src/ipcService.cpp @@ -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 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()); + } } diff --git a/modules/ipc/src/ipcService.h b/modules/ipc/src/ipcService.h index 5389a314dd8b..c58496c484a1 100644 --- a/modules/ipc/src/ipcService.h +++ b/modules/ipc/src/ipcService.h @@ -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 mObserver; }; -*/ + +typedef ipcQueue 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__ diff --git a/modules/ipc/test/TestIPC.cpp b/modules/ipc/test/TestIPC.cpp index f3a7b35f160d..4a90e269a3ef 100644 --- a/modules/ipc/test/TestIPC.cpp +++ b/modules/ipc/test/TestIPC.cpp @@ -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 obs(new myIpcClientObserver()); + ipcServ->QueryClientByName(NS_LITERAL_CSTRING("foopy"), obs, &reqToken); + while (gKeepRunning) gEventQ->ProcessPendingEvents();