This commit is contained in:
darin%netscape.com 2002-11-02 18:57:15 +00:00
Родитель 9b6ae7fdf7
Коммит a8e727269b
5 изменённых файлов: 202 добавлений и 23 удалений

Просмотреть файл

@ -59,7 +59,6 @@ enum {
IPCM_MSG_TYPE_CLIENT_DEL_TARGET, IPCM_MSG_TYPE_CLIENT_DEL_TARGET,
IPCM_MSG_TYPE_QUERY_CLIENT_BY_NAME, IPCM_MSG_TYPE_QUERY_CLIENT_BY_NAME,
IPCM_MSG_TYPE_QUERY_CLIENT_INFO, IPCM_MSG_TYPE_QUERY_CLIENT_INFO,
IPCM_MSG_TYPE_QUERY_FAILED,
IPCM_MSG_TYPE_FORWARD, IPCM_MSG_TYPE_FORWARD,
IPCM_MSG_TYPE_UNKNOWN // unknown message type IPCM_MSG_TYPE_UNKNOWN // unknown message type
}; };
@ -125,6 +124,10 @@ public:
PRUint32 Reason() const { return Second(); } PRUint32 Reason() const { return Second(); }
}; };
enum {
IPCM_ERROR_CLIENT_NOT_FOUND = 1
};
// //
// IPCM_MSG_TYPE_CLIENT_HELLO // IPCM_MSG_TYPE_CLIENT_HELLO
// //

Просмотреть файл

@ -56,14 +56,14 @@ public:
// message handlers // message handlers
// //
void handlePing(ipcClient *client, const ipcMessage *rawMsg) void OnPing(ipcClient *client, const ipcMessage *rawMsg)
{ {
LOG(("got PING\n")); LOG(("got PING\n"));
IPC_SendMsg(client, new ipcmMessagePing()); IPC_SendMsg(client, new ipcmMessagePing());
} }
void handleClientHello(ipcClient *client, const ipcMessage *rawMsg) void OnClientHello(ipcClient *client, const ipcMessage *rawMsg)
{ {
LOG(("got CLIENT_HELLO\n")); LOG(("got CLIENT_HELLO\n"));
@ -75,7 +75,23 @@ public:
IPC_SendMsg(client, new ipcmMessageClientID(client->ID())); 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")); LOG(("got FORWARD\n"));
@ -106,19 +122,19 @@ public:
{ {
static MsgHandler handlers[] = static MsgHandler handlers[] =
{ {
&ipcCommandModule::handlePing, &ipcCommandModule::OnPing,
NULL, // ERROR NULL, // ERROR
&ipcCommandModule::handleClientHello, &ipcCommandModule::OnClientHello,
NULL, // CLIENT_ID NULL, // CLIENT_ID
NULL, // CLIENT_INFO NULL, // CLIENT_INFO
NULL, // CLIENT_ADD_NAME NULL, // CLIENT_ADD_NAME
NULL, // CLIENT_DEL_NAME NULL, // CLIENT_DEL_NAME
NULL, // CLIENT_ADD_TARGET NULL, // CLIENT_ADD_TARGET
NULL, // CLIENT_DEL_TARGET NULL, // CLIENT_DEL_TARGET
NULL, // QUERY_CLIENT_BY_NAME &ipcCommandModule::OnQueryClientByName,
NULL, // QUERY_CLIENT_INFO NULL, // QUERY_CLIENT_INFO
NULL, // QUERY_FAILED NULL, // QUERY_FAILED
&ipcCommandModule::handleForward, &ipcCommandModule::OnForward,
}; };
int type = IPCM_GetMsgType(rawMsg); int type = IPCM_GetMsgType(rawMsg);

Просмотреть файл

@ -44,8 +44,13 @@
#include "ipcConfig.h" #include "ipcConfig.h"
#include "ipcLog.h" #include "ipcLog.h"
#include "ipcService.h" #include "ipcService.h"
#include "ipcMessageUtils.h"
#include "ipcm.h" #include "ipcm.h"
//-----------------------------------------------------------------------------
// helpers
//-----------------------------------------------------------------------------
static PRBool PR_CALLBACK static PRBool PR_CALLBACK
ipcReleaseMessageObserver(nsHashKey *aKey, void *aData, void* aClosure) ipcReleaseMessageObserver(nsHashKey *aKey, void *aData, void* aClosure)
{ {
@ -54,10 +59,44 @@ ipcReleaseMessageObserver(nsHashKey *aKey, void *aData, void* aClosure)
return PR_TRUE; 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 // ipcService
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
PRUint32 ipcService::gLastReqToken = 0;
ipcService::ipcService() ipcService::ipcService()
: mTransport(nsnull) : mTransport(nsnull)
, mClientID(0) , mClientID(0)
@ -114,6 +153,39 @@ ipcService::Init()
return NS_OK; 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 // interface impl
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -164,6 +236,11 @@ ipcService::QueryClientByName(const nsACString &name,
// //
// now queue up the observer and generate a token. // 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; return NS_OK;
} }
@ -240,17 +317,35 @@ ipcService::OnConnectionEstablished(PRUint32 clientID)
void void
ipcService::OnConnectionLost() ipcService::OnConnectionLost()
{ {
//
// XXX error out any pending queries
//
mClientID = 0; mClientID = 0;
} }
void void
ipcService::OnMessageAvailable(const ipcMessage *msg) ipcService::OnMessageAvailable(const ipcMessage *msg)
{ {
nsIDKey key(msg->Target()); if (msg->Target().Equals(IPCM_TARGET)) {
//
ipcIMessageObserver *observer = (ipcIMessageObserver *) mObserverDB.Get(&key); // all IPCM messages stop here.
if (observer) //
observer->OnMessageAvailable(msg->Target(), switch (IPCM_GetMsgType(msg)) {
msg->Data(), case IPCM_MSG_TYPE_CLIENT_ID:
msg->DataLen()); 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 "nsCOMPtr.h"
#include "nsHashtable.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 // ipcClientQuery
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
/*
class ipcClientQuery class ipcClientQuery
{ {
public: public:
@ -62,10 +85,12 @@ public:
{ } { }
ipcClientQuery *mNext; ipcClientQuery *mNext;
nsCString mName;
PRUint32 mReqToken; PRUint32 mReqToken;
nsCOMPtr<ipcIClientObserver> mObserver; nsCOMPtr<ipcIClientObserver> mObserver;
}; };
*/
typedef ipcQueue<ipcClientQuery> ipcClientQueryQ;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// ipcService // ipcService
@ -84,16 +109,21 @@ public:
nsresult Init(); nsresult Init();
private: private:
nsresult ErrorAccordingToIPCM(PRUint32 err);
void HandleQueryResult(const ipcMessage *, PRBool succeeded);
// ipcTransportObserver: // ipcTransportObserver:
void OnConnectionEstablished(PRUint32 clientID); void OnConnectionEstablished(PRUint32 clientID);
void OnConnectionLost(); void OnConnectionLost();
void OnMessageAvailable(const ipcMessage *); void OnMessageAvailable(const ipcMessage *);
static PRUint32 gLastReqToken;
nsHashtable mObserverDB; nsHashtable mObserverDB;
ipcTransport *mTransport; ipcTransport *mTransport;
PRUint32 mClientID; PRUint32 mClientID;
//ipcClientQuery *mQueryQ; ipcClientQueryQ mQueryQ;
}; };
#endif // !ipcService_h__ #endif // !ipcService_h__

Просмотреть файл

@ -41,7 +41,7 @@
#include "nsIEventQueueService.h" #include "nsIEventQueueService.h"
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsIComponentRegistrar.h" #include "nsIComponentRegistrar.h"
#include "nsLiteralString.h" #include "nsString.h"
static const nsID TestTargetID = static const nsID TestTargetID =
{ /* e628fc6e-a6a7-48c7-adba-f241d1128fb8 */ { /* e628fc6e-a6a7-48c7-adba-f241d1128fb8 */
@ -64,16 +64,15 @@ static nsIEventQueue* gEventQ = nsnull;
static PRBool gKeepRunning = PR_TRUE; static PRBool gKeepRunning = PR_TRUE;
//static PRInt32 gMsgCount = 0; //static PRInt32 gMsgCount = 0;
//-----------------------------------------------------------------------------
class myIpcMessageObserver : public ipcIMessageObserver class myIpcMessageObserver : public ipcIMessageObserver
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_IPCIMESSAGEOBSERVER NS_DECL_IPCIMESSAGEOBSERVER
myIpcMessageObserver() myIpcMessageObserver() { NS_INIT_ISUPPORTS(); }
{
NS_INIT_ISUPPORTS();
}
}; };
NS_IMPL_ISUPPORTS1(myIpcMessageObserver, ipcIMessageObserver) NS_IMPL_ISUPPORTS1(myIpcMessageObserver, ipcIMessageObserver)
@ -89,6 +88,38 @@ myIpcMessageObserver::OnMessageAvailable(const nsID &target, const char *data, P
return NS_OK; 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) void SendMsg(ipcIService *ipc, const nsID &target, const char *data, PRUint32 dataLen)
{ {
printf("*** sending message: [dataLen=%u]\n", 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"; "60 this is a really long message.\n";
SendMsg(ipcServ, TestTargetID, data, strlen(data)+1); SendMsg(ipcServ, TestTargetID, data, strlen(data)+1);
PRUint32 reqToken;
nsCOMPtr<ipcIClientObserver> obs(new myIpcClientObserver());
ipcServ->QueryClientByName(NS_LITERAL_CSTRING("foopy"), obs, &reqToken);
while (gKeepRunning) while (gKeepRunning)
gEventQ->ProcessPendingEvents(); gEventQ->ProcessPendingEvents();