1) introduce ipcIClientQueryHandler

2) ipcService impl cleanups
This commit is contained in:
darin%netscape.com 2002-11-11 22:07:26 +00:00
Родитель 1945b7684e
Коммит 5940356021
4 изменённых файлов: 181 добавлений и 116 удалений

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

@ -37,9 +37,9 @@
#include "nsISupports.idl"
interface nsISimpleEnumerator;
interface ipcIMessageObserver;
interface ipcIClientObserver;
interface ipcIClientQueryHandler;
/**
* the IPC service provides the means to communicate with an external IPC
@ -105,13 +105,13 @@ interface ipcIService : nsISupports
* or if there is no client matching the given name, the observer's
* onClientDown method will be called instead.
*
* @param aName name or alias of the client being queried.
* @param aObserver client observer to be notified.
* @param aName name of the client being queried.
* @param aHandler handler to be notified asynchronously of result.
*
* @return integer token identifying this request.
* @return integer value identifying this query.
*/
unsigned long queryClientByName(in ACString aName,
in ipcIClientObserver aObserver);
unsigned long queryClientByName(in ACString aName,
in ipcIClientQueryHandler aHandler);
/**
* query info about a particular client given its client ID. the observer's
@ -119,10 +119,20 @@ interface ipcIService : nsISupports
* is no client matching the given name, the observer's onClientDown method
* will be called instead.
*
* @return integer token identifying this request.
* @param aClientID ID of the client being queried.
* @param aHandler handler to be notified asynchronously of result.
*
* @return integer value identifying this query.
*/
unsigned long queryClientByID(in unsigned long aClientID,
in ipcIClientObserver aObserver);
unsigned long queryClientByID(in unsigned long aClientID,
in ipcIClientQueryHandler aHandler);
/**
* called to cancel a pending query.
*
* @param aQueryID return value from one of the "query" methods.
*/
void cancelQuery(in unsigned long aQueryID);
/**
* set client observer. observer's onClientUp method is called whenever
@ -159,7 +169,7 @@ interface ipcIService : nsISupports
*/
void sendMessage(in unsigned long aClientID,
in nsIDRef aTarget,
[array, const, size_is(aDataLen)]
[array, const, size_is(aDataLen)]
in octet aData,
in unsigned long aDataLen);
};
@ -176,7 +186,7 @@ interface ipcIMessageObserver : nsISupports
* @param aDataLen the data length of the message.
*/
void onMessageAvailable(in nsIDRef aTarget,
[array, const, size_is(aDataLen)]
[array, const, size_is(aDataLen)]
in octet aData,
in unsigned long aDataLen);
};
@ -184,20 +194,27 @@ interface ipcIMessageObserver : nsISupports
[scriptable, uuid(42283079-030c-4b13-b069-a08b7ad5eab2)]
interface ipcIClientObserver : nsISupports
{
void onClientUp (in unsigned long aReqToken,
in unsigned long aClientID);
const unsigned long CLIENT_UP = 1;
const unsigned long CLIENT_DOWN = 2;
void onClientStatus(in unsigned long aClientID,
in unsigned long aClientStatus);
};
void onClientDown (in unsigned long aReqToken,
in unsigned long aClientID);
[scriptable, uuid(6fefea5c-f747-4bb0-972f-2a7b363a01db)]
interface ipcIClientQueryHandler : nsISupports
{
void onQueryComplete(in unsigned long aQueryID,
in unsigned long aClientID,
[array, size_is(aNameCount)]
in string aClientNames,
in unsigned long aNameCount,
[array, const, size_is(aTargetCount)]
in nsIDPtr aClientTargets,
in unsigned long aTargetCount);
void onClientInfo (in unsigned long aReqToken,
in unsigned long aClientID,
[array, size_is(aNameCount)]
in string aClientNames,
in unsigned long aNameCount,
[array, const, size_is(aTargetCount)]
in nsIDPtr aClientTargets,
in unsigned long aTargetCount);
void onQueryFailed(in unsigned long aQueryID,
in nsresult aReason);
};
%{C++

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

@ -64,12 +64,84 @@ ipcReleaseMessageObserver(nsHashKey *aKey, void *aData, void* aClosure)
return PR_TRUE;
}
//----------------------------------------------------------------------------
// ipcClientQuery
//----------------------------------------------------------------------------
class ipcClientQuery
{
public:
ipcClientQuery(PRUint32 cID, ipcIClientQueryHandler *handler)
: mNext(nsnull)
, mQueryID(++gLastQueryID)
, mClientID(cID)
, mHandler(handler)
{ }
static PRUint32 gLastQueryID;
void SetClientID(PRUint32 cID) { mClientID = cID; }
void OnQueryComplete(const ipcmMessageClientInfo *msg);
void OnQueryFailed(nsresult reason);
PRUint32 QueryID() { return mQueryID; }
PRBool IsCanceled() { return mHandler == nsnull; }
ipcClientQuery *mNext;
private:
PRUint32 mQueryID;
PRUint32 mClientID;
nsCOMPtr<ipcIClientQueryHandler> mHandler;
};
PRUint32 ipcClientQuery::gLastQueryID = 0;
void
ipcClientQuery::OnQueryComplete(const ipcmMessageClientInfo *msg)
{
NS_ASSERTION(mHandler, "no handler");
PRUint32 nameCount = msg->NameCount();
PRUint32 targetCount = msg->TargetCount();
PRUint32 i;
const char **names = (const char **) malloc(nameCount * sizeof(char *));
const char *lastName = NULL;
for (i = 0; i < nameCount; ++i) {
lastName = msg->NextName(lastName);
names[i] = lastName;
}
const nsID **targets = (const nsID **) malloc(targetCount * sizeof(nsID *));
const nsID *lastTarget = NULL;
for (i = 0; i < targetCount; ++i) {
lastTarget = msg->NextTarget(lastTarget);
targets[i] = lastTarget;
}
mHandler->OnQueryComplete(mQueryID,
mClientID,
names, nameCount,
targets, targetCount);
free(names);
free(targets);
}
void
ipcClientQuery::OnQueryFailed(nsresult status)
{
NS_ASSERTION(mHandler, "no handler");
mHandler->OnQueryFailed(mQueryID, status);
mHandler = nsnull;
}
//-----------------------------------------------------------------------------
// ipcService
//-----------------------------------------------------------------------------
PRUint32 ipcService::gLastReqToken = 0;
ipcService::ipcService()
: mTransport(nsnull)
, mClientID(0)
@ -133,17 +205,19 @@ ipcService::OnIPCMClientID(const ipcmMessageClientID *msg)
return;
}
PRUint32 cID = msg->ClientID();
//
// (1) store client ID in query
// (2) move query to end of queue
// (3) issue CLIENT_INFO request
//
query->mID = msg->ClientID();
query->SetClientID(cID);
mQueryQ.RemoveFirst();
mQueryQ.Append(query);
mTransport->SendMsg(new ipcmMessageQueryClientInfo(query->mID));
mTransport->SendMsg(new ipcmMessageQueryClientInfo(cID));
}
void
@ -157,39 +231,16 @@ ipcService::OnIPCMClientInfo(const ipcmMessageClientInfo *msg)
return;
}
PRUint32 nameCount = msg->NameCount();
PRUint32 targetCount = msg->TargetCount();
PRUint32 i;
const char **names = (const char **) calloc(nameCount, sizeof(char *));
const char *lastName = NULL;
for (i = 0; i < nameCount; ++i) {
lastName = msg->NextName(lastName);
names[i] = lastName;
}
const nsID **targets = (const nsID **) calloc(targetCount, sizeof(nsID *));
const nsID *lastTarget = NULL;
for (i = 0; i < targetCount; ++i) {
lastTarget = msg->NextTarget(lastTarget);
targets[i] = lastTarget;
}
query->mObserver->OnClientInfo(query->mReqToken,
query->mID,
names, nameCount,
targets, targetCount);
if (!query->IsCanceled())
query->OnQueryComplete(msg);
mQueryQ.DeleteFirst();
free(names);
free(targets);
}
void
ipcService::OnIPCMError(const ipcmMessageError *msg)
{
LOG(("ipcService::OnIPCMError\n"));
LOG(("ipcService::OnIPCMError [reason=0x%08x]\n", msg->Reason()));
ipcClientQuery *query = mQueryQ.First();
if (!query) {
@ -197,8 +248,8 @@ ipcService::OnIPCMError(const ipcmMessageError *msg)
return;
}
query->mObserver->OnClientDown(query->mReqToken,
query->mID);
if (!query->IsCanceled())
query->OnQueryFailed(NS_ERROR_FAILURE);
mQueryQ.DeleteFirst();
}
@ -251,8 +302,8 @@ ipcService::RemoveClientName(const nsACString &name)
NS_IMETHODIMP
ipcService::QueryClientByName(const nsACString &name,
ipcIClientObserver *observer,
PRUint32 *token)
ipcIClientQueryHandler *handler,
PRUint32 *queryID)
{
if (!mTransport)
return NS_ERROR_NOT_AVAILABLE;
@ -268,23 +319,51 @@ ipcService::QueryClientByName(const nsACString &name,
rv = mTransport->SendMsg(msg);
if (NS_FAILED(rv)) return rv;
//
// now queue up the observer and generate a token.
//
ipcClientQuery *query = new ipcClientQuery();
query->mName = name;
query->mReqToken = *token = ++gLastReqToken;
query->mObserver = observer;
ipcClientQuery *query = new ipcClientQuery(0, handler);
if (queryID)
*queryID = query->QueryID();
mQueryQ.Append(query);
return NS_OK;
}
NS_IMETHODIMP
ipcService::QueryClientByID(PRUint32 clientID,
ipcIClientObserver *observer,
PRUint32 *token)
ipcIClientQueryHandler *handler,
PRUint32 *queryID)
{
return NS_ERROR_NOT_IMPLEMENTED;
if (!mTransport)
return NS_ERROR_NOT_AVAILABLE;
ipcMessage *msg;
msg = new ipcmMessageQueryClientInfo(clientID);
if (!msg)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv;
rv = mTransport->SendMsg(msg);
if (NS_FAILED(rv)) return rv;
ipcClientQuery *query = new ipcClientQuery(clientID, handler);
if (queryID)
*queryID = query->QueryID();
mQueryQ.Append(query);
return NS_OK;
}
NS_IMETHODIMP
ipcService::CancelQuery(PRUint32 queryID)
{
ipcClientQuery *query = mQueryQ.First();
while (query) {
if (query->QueryID() == queryID) {
query->OnQueryFailed(NS_ERROR_ABORT);
break;
}
query = query->mNext;
}
return NS_OK;
}
NS_IMETHODIMP
@ -379,7 +458,7 @@ ipcService::OnConnectionLost()
//
while (mQueryQ.First()) {
ipcClientQuery *query = mQueryQ.First();
query->mObserver->OnClientDown(query->mReqToken, query->mID);
query->OnQueryFailed(NS_ERROR_ABORT);
mQueryQ.DeleteFirst();
}

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

@ -51,27 +51,7 @@
#include "ipcMessageQ.h"
#include "ipcm.h"
//----------------------------------------------------------------------------
// ipcClientQuery
//----------------------------------------------------------------------------
class ipcClientQuery
{
public:
ipcClientQuery()
: mNext(nsnull)
, mID(0)
, mReqToken(0)
{ }
ipcClientQuery *mNext;
nsCString mName;
PRUint32 mID;
PRUint32 mReqToken;
nsCOMPtr<ipcIClientObserver> mObserver;
};
typedef ipcList<ipcClientQuery> ipcClientQueryQ;
typedef ipcList<class ipcClientQuery> ipcClientQueryQ;
//----------------------------------------------------------------------------
// ipcService
@ -100,8 +80,6 @@ private:
void OnConnectionLost();
void OnMessageAvailable(const ipcMessage *);
static PRUint32 gLastReqToken;
nsHashtable mObserverDB;
ipcTransport *mTransport;
PRUint32 mClientID;

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

@ -109,42 +109,33 @@ myIpcMessageObserver::OnMessageAvailable(const nsID &target, const PRUint8 *data
//-----------------------------------------------------------------------------
class myIpcClientObserver : public ipcIClientObserver
class myIpcClientQueryHandler : public ipcIClientQueryHandler
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IPCICLIENTOBSERVER
NS_DECL_IPCICLIENTQUERYHANDLER
myIpcClientObserver() { NS_INIT_ISUPPORTS(); }
myIpcClientQueryHandler() { NS_INIT_ISUPPORTS(); }
};
NS_IMPL_ISUPPORTS1(myIpcClientObserver, ipcIClientObserver)
NS_IMPL_ISUPPORTS1(myIpcClientQueryHandler, ipcIClientQueryHandler)
NS_IMETHODIMP
myIpcClientObserver::OnClientUp(PRUint32 aReqToken,
PRUint32 aClientID)
myIpcClientQueryHandler::OnQueryFailed(PRUint32 aQueryID, nsresult aReason)
{
printf("*** got client up [token=%u clientID=%u]\n", aReqToken, aClientID);
printf("*** query failed [queryID=%u reason=0x%08x]\n", aQueryID, aReason);
return NS_OK;
}
NS_IMETHODIMP
myIpcClientObserver::OnClientDown(PRUint32 aReqToken,
PRUint32 aClientID)
myIpcClientQueryHandler::OnQueryComplete(PRUint32 aQueryID,
PRUint32 aClientID,
const char **aNames,
PRUint32 aNameCount,
const nsID **aTargets,
PRUint32 aTargetCount)
{
printf("*** got client down [token=%u clientID=%u]\n", aReqToken, aClientID);
return NS_OK;
}
NS_IMETHODIMP
myIpcClientObserver::OnClientInfo(PRUint32 aReqToken,
PRUint32 aClientID,
const char **aNames,
PRUint32 aNameCount,
const nsID **aTargets,
PRUint32 aTargetCount)
{
printf("*** got client info [token=%u clientID=%u]\n", aReqToken, aClientID);
printf("*** query complete [queryID=%u clientID=%u]\n", aQueryID, aClientID);
PRUint32 i;
printf("*** names:\n");
@ -277,9 +268,9 @@ int main(int argc, char **argv)
"60 this is a really long message.\n";
SendMsg(ipcServ, 0, kTestTargetID, data, strlen(data)+1);
PRUint32 reqToken;
nsCOMPtr<ipcIClientObserver> obs(new myIpcClientObserver());
ipcServ->QueryClientByName(NS_LITERAL_CSTRING("foopy"), obs, &reqToken);
PRUint32 queryID;
nsCOMPtr<ipcIClientQueryHandler> handler(new myIpcClientQueryHandler());
ipcServ->QueryClientByName(NS_LITERAL_CSTRING("foopy"), handler, &queryID);
while (gKeepRunning)
gEventQ->ProcessPendingEvents();