зеркало из https://github.com/mozilla/pjs.git
1) introduce ipcIClientQueryHandler
2) ipcService impl cleanups
This commit is contained in:
Родитель
1945b7684e
Коммит
5940356021
|
@ -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();
|
||||
|
|
Загрузка…
Ссылка в новой задаче