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_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();