diff --git a/modules/ipc/daemon/ipcClient.cpp b/modules/ipc/daemon/ipcClient.cpp index fdd07ec18523..1cbe3f829b25 100644 --- a/modules/ipc/daemon/ipcClient.cpp +++ b/modules/ipc/daemon/ipcClient.cpp @@ -60,10 +60,6 @@ ipcClient::Init() // every client must be able to handle IPCM messages. mTargets.Append(IPCM_TARGET); - -#ifdef XP_UNIX - mInMsg = new ipcMessage(); -#endif } // @@ -76,8 +72,7 @@ ipcClient::Finalize() mTargets.DeleteAll(); #ifdef XP_UNIX - if (mInMsg) - delete mInMsg; + mInMsg.Reset(); mOutMsgQ.DeleteAll(); #endif } @@ -173,11 +168,11 @@ ipcClient::Process(PRFileDesc *fd, int poll_flags) PRUint32 nread; PRBool complete; - mInMsg->ReadFrom(ptr, PRUint32(n), &nread, &complete); + mInMsg.ReadFrom(ptr, PRUint32(n), &nread, &complete); if (complete) { - IPC_DispatchMsg(this, mInMsg); - mInMsg->Reset(); + IPC_DispatchMsg(this, &mInMsg); + mInMsg.Reset(); } n -= nread; diff --git a/modules/ipc/daemon/ipcClient.h b/modules/ipc/daemon/ipcClient.h index 9cc72448af3a..859c24e23e30 100644 --- a/modules/ipc/daemon/ipcClient.h +++ b/modules/ipc/daemon/ipcClient.h @@ -126,7 +126,7 @@ private: #endif #ifdef XP_UNIX - ipcMessage *mInMsg; // buffer for incoming message + ipcMessage mInMsg; // buffer for incoming message ipcMessageQ mOutMsgQ; // outgoing message queue // keep track of the amount of the first message sent diff --git a/modules/ipc/daemon/ipcCommandModule.cpp b/modules/ipc/daemon/ipcCommandModule.cpp index 433cd9d06346..8d38ff2bac5c 100644 --- a/modules/ipc/daemon/ipcCommandModule.cpp +++ b/modules/ipc/daemon/ipcCommandModule.cpp @@ -45,159 +45,134 @@ #include "ipcd.h" #include "ipcm.h" -struct ipcCommandModule +typedef void (* ipcmMsgHandler)(ipcClient *, const ipcMessage *); + +// +// message handlers +// + +static void +ipcm_OnPing(ipcClient *client, const ipcMessage *rawMsg) { - typedef void (* MsgHandler)(ipcClient *, const ipcMessage *); + LOG(("got PING\n")); - // - // message handlers - // - - static void OnPing(ipcClient *client, const ipcMessage *rawMsg) - { - LOG(("got PING\n")); - - ipcmMessagePing out; - IPC_SendMsg(client, &out); - } - - static void OnClientHello(ipcClient *client, const ipcMessage *rawMsg) - { - LOG(("got CLIENT_HELLO\n")); - - ipcMessageCast msg(rawMsg); - const char *name = msg->PrimaryName(); - if (name) - client->AddName(name); - - ipcmMessageClientID out(client->ID()); - IPC_SendMsg(client, &out); - } - - static void OnClientAddName(ipcClient *client, const ipcMessage *rawMsg) - { - LOG(("got CLIENT_ADD_NAME\n")); - - ipcMessageCast msg(rawMsg); - const char *name = msg->Name(); - if (name) - client->AddName(name); - } - - static void OnClientDelName(ipcClient *client, const ipcMessage *rawMsg) - { - LOG(("got CLIENT_DEL_NAME\n")); - - ipcMessageCast msg(rawMsg); - const char *name = msg->Name(); - if (name) - client->DelName(name); - } - - static void OnClientAddTarget(ipcClient *client, const ipcMessage *rawMsg) - { - LOG(("got CLIENT_ADD_TARGET\n")); - - ipcMessageCast msg(rawMsg); - client->AddTarget(msg->Target()); - } - - static void OnClientDelTarget(ipcClient *client, const ipcMessage *rawMsg) - { - LOG(("got CLIENT_DEL_TARGET\n")); - - ipcMessageCast msg(rawMsg); - client->DelTarget(msg->Target()); - } - - static 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())); - ipcmMessageClientID out(result->ID()); - IPC_SendMsg(client, &out); - } - else { - LOG((" client does not exist\n")); - ipcmMessageError out(IPCM_ERROR_CLIENT_NOT_FOUND); - IPC_SendMsg(client, &out); - } - } - - static void OnForward(ipcClient *client, const ipcMessage *rawMsg) - { - LOG(("got FORWARD\n")); - - ipcMessageCast msg(rawMsg); - PRUint32 destID = msg->DestClientID(); - - ipcMessage newMsg; - newMsg.Init(msg->InnerTarget(), - msg->InnerData(), - msg->InnerDataLen()); - - ipcClient *dest = IPC_GetClientByID(destID); - if (!dest) { - LOG((" destination client not found!\n")); - return; - } - IPC_SendMsg(dest, &newMsg); - } - - // - // ipcModule interface impl - // - - static void Init() - { - } - - static void Shutdown() - { - } - - static void HandleMsg(ipcClient *client, const ipcMessage *rawMsg) - { - static MsgHandler handlers[] = - { - OnPing, - NULL, // ERROR - OnClientHello, - NULL, // CLIENT_ID - NULL, // CLIENT_INFO - OnClientAddName, - OnClientDelName, - OnClientAddTarget, - OnClientDelTarget, - OnQueryClientByName, - NULL, // QUERY_CLIENT_INFO - OnForward, - }; - - int type = IPCM_GetMsgType(rawMsg); - LOG(("ipcCommandModule::HandleMsg [type=%d]\n", type)); - - if (type < IPCM_MSG_TYPE_UNKNOWN) { - if (handlers[type]) { - MsgHandler handler = handlers[type]; - handler(client, rawMsg); - } - } - } -}; - -ipcModuleMethods *IPC_GetCommandModuleMethods() -{ - static ipcModuleMethods methods = - { - IPC_MODULE_METHODS_VERSION, - ipcCommandModule::Init, - ipcCommandModule::Shutdown, - ipcCommandModule::HandleMsg - }; - return &methods; + IPC_SendMsg(client, new ipcmMessagePing()); +} + +static void +ipcm_OnClientHello(ipcClient *client, const ipcMessage *rawMsg) +{ + LOG(("got CLIENT_HELLO\n")); + + ipcMessageCast msg(rawMsg); + const char *name = msg->PrimaryName(); + if (name) + client->AddName(name); + + IPC_SendMsg(client, new ipcmMessageClientID(client->ID())); +} + +static void +ipcm_OnClientAddName(ipcClient *client, const ipcMessage *rawMsg) +{ + LOG(("got CLIENT_ADD_NAME\n")); + + ipcMessageCast msg(rawMsg); + const char *name = msg->Name(); + if (name) + client->AddName(name); +} + +static void +ipcm_OnClientDelName(ipcClient *client, const ipcMessage *rawMsg) +{ + LOG(("got CLIENT_DEL_NAME\n")); + + ipcMessageCast msg(rawMsg); + const char *name = msg->Name(); + if (name) + client->DelName(name); +} + +static void +ipcm_OnClientAddTarget(ipcClient *client, const ipcMessage *rawMsg) +{ + LOG(("got CLIENT_ADD_TARGET\n")); + + ipcMessageCast msg(rawMsg); + client->AddTarget(msg->Target()); +} + +static void +ipcm_OnClientDelTarget(ipcClient *client, const ipcMessage *rawMsg) +{ + LOG(("got CLIENT_DEL_TARGET\n")); + + ipcMessageCast msg(rawMsg); + client->DelTarget(msg->Target()); +} + +static void +ipcm_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)); + } +} + +static void +ipcm_OnForward(ipcClient *client, const ipcMessage *rawMsg) +{ + LOG(("got FORWARD\n")); + + ipcMessageCast msg(rawMsg); + + ipcClient *dest = IPC_GetClientByID(msg->DestClientID()); + if (!dest) { + LOG((" destination client not found!\n")); + return; + } + ipcMessage *newMsg = new ipcMessage(msg->InnerTarget(), + msg->InnerData(), + msg->InnerDataLen()); + IPC_SendMsg(dest, newMsg); +} + +void +IPCM_HandleMsg(ipcClient *client, const ipcMessage *rawMsg) +{ + static ipcmMsgHandler handlers[] = + { + ipcm_OnPing, + NULL, // ERROR + ipcm_OnClientHello, + NULL, // CLIENT_ID + NULL, // CLIENT_INFO + ipcm_OnClientAddName, + ipcm_OnClientDelName, + ipcm_OnClientAddTarget, + ipcm_OnClientDelTarget, + ipcm_OnQueryClientByName, + NULL, // QUERY_CLIENT_INFO + ipcm_OnForward, + }; + + int type = IPCM_GetMsgType(rawMsg); + LOG(("ipcCommandModule::HandleMsg [type=%d]\n", type)); + + if (type < IPCM_MSG_TYPE_UNKNOWN) { + if (handlers[type]) { + ipcmMsgHandler handler = handlers[type]; + handler(client, rawMsg); + } + } } diff --git a/modules/ipc/daemon/ipcCommandModule.h b/modules/ipc/daemon/ipcCommandModule.h index 9ffede61428e..ea146cdcffac 100644 --- a/modules/ipc/daemon/ipcCommandModule.h +++ b/modules/ipc/daemon/ipcCommandModule.h @@ -40,6 +40,9 @@ #include "ipcm.h" // for IPCM_TARGET -struct ipcModuleMethods *IPC_GetCommandModuleMethods(); +class ipcClient; +class ipcMessage; + +void IPCM_HandleMsg(ipcClient *, const ipcMessage *); #endif // !ipcCommandModule_h__ diff --git a/modules/ipc/daemon/ipcModule.h b/modules/ipc/daemon/ipcModule.h index 1a5b5344d83d..908549db63a7 100644 --- a/modules/ipc/daemon/ipcModule.h +++ b/modules/ipc/daemon/ipcModule.h @@ -87,17 +87,20 @@ struct ipcModuleMethods // // params: // - // client - an opaque "handle" to an object representing the client that - // sent the message. modules should not store the value of this - // beyond the duration fo this function call. (e.g., the handle - // may be invalid after this function call returns.) modules - // wishing to hold onto a reference to a "client" should store - // the client's ID (see IPC_GetClientID). + // client - an opaque "handle" to an object representing the client that + // sent the message. modules should not store the value of this + // beyond the duration fo this function call. (e.g., the handle + // may be invalid after this function call returns.) modules + // wishing to hold onto a reference to a "client" should store + // the client's ID (see IPC_GetClientID). + // target - message target + // data - message data + // dataLen - message data length // - // msg - the message sent from the client. the target of this message - // matches the ID of this module. - // - void (* handleMsg) (ipcClientHandle client, const ipcMessage *msg); + void (* handleMsg) (ipcClientHandle client, + const nsID &target, + const void *data, + PRUint32 dataLen); }; //----------------------------------------------------------------------------- @@ -124,15 +127,20 @@ struct ipcDaemonMethods // called to send a message to another module. // // params: - // client - identifies the client from which this message originated. - // msg - the message to dispatch. + // client - identifies the client from which this message originated. + // target - message target + // data - message data + // dataLen - message data length // // returns: // PR_SUCCESS if message was dispatched. // PR_FAILURE if message could not be dispatched (possibly because // no module is registered for the given message target). // - PRStatus (* dispatchMsg) (ipcClientHandle client, const ipcMessage *msg); + PRStatus (* dispatchMsg) (ipcClientHandle client, + const nsID &target, + const void *data, + PRUint32 dataLen); // // called to send a message to a particular client or to broadcast a @@ -141,6 +149,7 @@ struct ipcDaemonMethods // params: // client - if null, then broadcast message to all clients. otherwise, // send message to the client specified. + // XXX:FIXME // msg - the message to send. // // returns: @@ -148,7 +157,10 @@ struct ipcDaemonMethods // PR_FAILURE if message could not be sent (possibly because the client // does not have a registered observer for the msg's target). // - PRStatus (* sendMsg) (ipcClientHandle client, const ipcMessage *msg); + PRStatus (* sendMsg) (ipcClientHandle client, + const nsID &target, + const void *data, + PRUint32 dataLen); // // called to lookup a client handle given its client ID. each client has diff --git a/modules/ipc/daemon/ipcModuleReg.cpp b/modules/ipc/daemon/ipcModuleReg.cpp index d1a8b0a5af17..416a4f70cf21 100644 --- a/modules/ipc/daemon/ipcModuleReg.cpp +++ b/modules/ipc/daemon/ipcModuleReg.cpp @@ -150,49 +150,45 @@ IPC_GetModuleByTarget(const nsID &target) void IPC_InitModuleReg(const char *exePath) { - // - // register built-in modules - // - AddModule(IPCM_TARGET, IPC_GetCommandModuleMethods(), NULL); + if (!(exePath && *exePath)) + return; // // register plug-in modules // - if (exePath && *exePath) { - static const char relModDir[] = "ipc/modules"; + static const char relModDir[] = "ipc/modules"; - char *p = PL_strrchr(exePath, IPC_PATH_SEP_CHAR); - if (p == NULL) { - LOG(("unexpected exe path\n")); - return; - } - - int baseLen = p - exePath; - int finalLen = baseLen + 1 + sizeof(relModDir); - - // build full path to ipc modules - char *modulesDir = (char*) malloc(finalLen); - memcpy(modulesDir, exePath, baseLen); - modulesDir[baseLen] = IPC_PATH_SEP_CHAR; - memcpy(modulesDir + baseLen + 1, relModDir, sizeof(relModDir)); - - LOG(("loading libraries in %s\n", modulesDir)); - // - // scan directory for IPC modules - // - PRDir *dir = PR_OpenDir(modulesDir); - if (dir) { - PRDirEntry *ent; - while ((ent = PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) { - // - // locate extension, and check if dynamic library - // - char *p = strrchr(ent->name, '.'); - if (p && PL_strcasecmp(p, MOZ_DLL_SUFFIX) == 0) - InitModuleFromLib(modulesDir, ent->name); - } - PR_CloseDir(dir); + char *p = PL_strrchr(exePath, IPC_PATH_SEP_CHAR); + if (p == NULL) { + LOG(("unexpected exe path\n")); + return; + } + + int baseLen = p - exePath; + int finalLen = baseLen + 1 + sizeof(relModDir); + + // build full path to ipc modules + char *modulesDir = (char*) malloc(finalLen); + memcpy(modulesDir, exePath, baseLen); + modulesDir[baseLen] = IPC_PATH_SEP_CHAR; + memcpy(modulesDir + baseLen + 1, relModDir, sizeof(relModDir)); + + LOG(("loading libraries in %s\n", modulesDir)); + // + // scan directory for IPC modules + // + PRDir *dir = PR_OpenDir(modulesDir); + if (dir) { + PRDirEntry *ent; + while ((ent = PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) { + // + // locate extension, and check if dynamic library + // + char *p = strrchr(ent->name, '.'); + if (p && PL_strcasecmp(p, MOZ_DLL_SUFFIX) == 0) + InitModuleFromLib(modulesDir, ent->name); } + PR_CloseDir(dir); } } diff --git a/modules/ipc/daemon/ipcModuleUtil.h b/modules/ipc/daemon/ipcModuleUtil.h index 56620897519e..590eac365be1 100644 --- a/modules/ipc/daemon/ipcModuleUtil.h +++ b/modules/ipc/daemon/ipcModuleUtil.h @@ -48,17 +48,17 @@ extern ipcDaemonMethods *gIPCDaemonMethods; //----------------------------------------------------------------------------- inline PRStatus -IPC_DispatchMsg(ipcClientHandle client, const ipcMessage *msg) +IPC_DispatchMsg(ipcClientHandle client, const nsID &target, const void *data, PRUint32 dataLen) { PR_ASSERT(gIPCDaemonMethods); - return gIPCDaemonMethods->dispatchMsg(client, msg); + return gIPCDaemonMethods->dispatchMsg(client, target, data, dataLen); } inline PRStatus -IPC_SendMsg(ipcClientHandle client, const ipcMessage *msg) +IPC_SendMsg(ipcClientHandle client, const nsID &target, const void *data, PRUint32 dataLen) { PR_ASSERT(gIPCDaemonMethods); - return gIPCDaemonMethods->sendMsg(client, msg); + return gIPCDaemonMethods->sendMsg(client, target, data, dataLen); } inline ipcClientHandle @@ -129,12 +129,12 @@ IPC_EnumClientTargets(ipcClientHandle client, ipcClientTargetEnumFunc func, void //----------------------------------------------------------------------------- inline PRStatus -IPC_SendMsg(PRUint32 clientID, ipcMessage *msg) +IPC_SendMsg(PRUint32 clientID, const nsID &target, const void *data, PRUint32 dataLen) { ipcClient *client = IPC_GetClientByID(clientID); if (!client) return PR_FAILURE; - return IPC_SendMsg(client, msg); + return IPC_SendMsg(client, target, data, dataLen); } //----------------------------------------------------------------------------- diff --git a/modules/ipc/daemon/ipcd.cpp b/modules/ipc/daemon/ipcd.cpp index 7a496ec1ca19..d04cc91aa6ca 100644 --- a/modules/ipc/daemon/ipcd.cpp +++ b/modules/ipc/daemon/ipcd.cpp @@ -41,20 +41,52 @@ #include "ipcClient.h" #include "ipcModuleReg.h" #include "ipcModule.h" +#include "ipcCommandModule.h" #include "ipcdPrivate.h" #include "ipcd.h" -//----------------------------------------------------------------------------- -// IPC API -//----------------------------------------------------------------------------- - PRStatus IPC_DispatchMsg(ipcClient *client, const ipcMessage *msg) +{ + if (msg->Target().Equals(IPCM_TARGET)) { + IPCM_HandleMsg(client, msg); + return PR_SUCCESS; + } + + return IPC_DispatchMsg(client, msg->Target(), msg->Data(), msg->DataLen()); +} + +PRStatus +IPC_SendMsg(ipcClient *client, ipcMessage *msg) +{ + if (client == NULL) { + // + // broadcast + // + for (int i=0; iClone()); + delete msg; + return PR_SUCCESS; + } + + if (client->HasTarget(msg->Target())) + return IPC_PlatformSendMsg(client, msg); + + LOG((" no registered message handler\n")); + return PR_FAILURE; +} + +//----------------------------------------------------------------------------- +// IPC daemon methods +//----------------------------------------------------------------------------- + +PRStatus +IPC_DispatchMsg(ipcClient *client, const nsID &target, const void *data, PRUint32 dataLen) { // lookup handler for this message's topic and forward message to it. - ipcModuleMethods *methods = IPC_GetModuleByTarget(msg->Target()); + ipcModuleMethods *methods = IPC_GetModuleByTarget(target); if (methods) { - methods->handleMsg(client, msg); + methods->handleMsg(client, target, data, dataLen); return PR_SUCCESS; } LOG(("no registered module; ignoring message\n")); @@ -62,25 +94,9 @@ IPC_DispatchMsg(ipcClient *client, const ipcMessage *msg) } PRStatus -IPC_SendMsg(ipcClient *client, const ipcMessage *msg) +IPC_SendMsg(ipcClient *client, const nsID &target, const void *data, PRUint32 dataLen) { - LOG(("IPC_SendMsg [clientID=%u]\n", client->ID())); - - if (client == NULL) { - // - // broadcast - // - for (int i=0; iHasTarget(msg->Target())) - IPC_PlatformSendMsg(&ipcClients[i], msg); - } - return PR_SUCCESS; - } - if (!client->HasTarget(msg->Target())) { - LOG((" no registered message handler\n")); - return PR_FAILURE; - } - return IPC_PlatformSendMsg(client, msg); + return IPC_SendMsg(client, new ipcMessage(target, (const char *) data, dataLen)); } ipcClient * diff --git a/modules/ipc/daemon/ipcd.h b/modules/ipc/daemon/ipcd.h index 540534d765a8..95f83caab84e 100644 --- a/modules/ipc/daemon/ipcd.h +++ b/modules/ipc/daemon/ipcd.h @@ -39,6 +39,7 @@ #define IPCD_H__ #include "ipcModule.h" +#include "ipcMessage.h" //----------------------------------------------------------------------------- // IPC daemon methods (see struct ipcDaemonMethods) @@ -47,8 +48,8 @@ // modules must access these through the ipcDaemonMethods structure. //----------------------------------------------------------------------------- -PRStatus IPC_DispatchMsg (ipcClientHandle client, const ipcMessage *msg); -PRStatus IPC_SendMsg (ipcClientHandle client, const ipcMessage *msg); +PRStatus IPC_DispatchMsg (ipcClientHandle client, const nsID &target, const void *data, PRUint32 dataLen); +PRStatus IPC_SendMsg (ipcClientHandle client, const nsID &target, const void *data, PRUint32 dataLen); ipcClientHandle IPC_GetClientByID (PRUint32 id); ipcClientHandle IPC_GetClientByName (const char *name); void IPC_EnumClients (ipcClientEnumFunc func, void *closure); @@ -59,4 +60,18 @@ PRBool IPC_ClientHasTarget (ipcClientHandle client, const nsID &ta void IPC_EnumClientNames (ipcClientHandle client, ipcClientNameEnumFunc func, void *closure); void IPC_EnumClientTargets (ipcClientHandle client, ipcClientTargetEnumFunc func, void *closure); +//----------------------------------------------------------------------------- +// ipcMessage equivalents... +//----------------------------------------------------------------------------- + +// +// dispatch message +// +PRStatus IPC_DispatchMsg(ipcClientHandle client, const ipcMessage *msg); + +// +// send message, takes ownership of |msg|. +// +PRStatus IPC_SendMsg(ipcClientHandle client, ipcMessage *msg); + #endif // !IPCD_H__ diff --git a/modules/ipc/daemon/ipcdPrivate.h b/modules/ipc/daemon/ipcdPrivate.h index 34c3237fc15b..f2a2ccbc88fe 100644 --- a/modules/ipc/daemon/ipcdPrivate.h +++ b/modules/ipc/daemon/ipcdPrivate.h @@ -16,8 +16,8 @@ extern ipcClient *ipcClients; extern int ipcClientCount; // -// platform specific send message function. +// platform specific send message function, takes ownership of |msg|. // -PRStatus IPC_PlatformSendMsg(ipcClient *client, const ipcMessage *msg); +PRStatus IPC_PlatformSendMsg(ipcClient *client, ipcMessage *msg); #endif // !ipcdPrivate_h__ diff --git a/modules/ipc/daemon/ipcdUnix.cpp b/modules/ipc/daemon/ipcdUnix.cpp index ab062aefde8a..05b3d82dd390 100644 --- a/modules/ipc/daemon/ipcdUnix.cpp +++ b/modules/ipc/daemon/ipcdUnix.cpp @@ -340,14 +340,14 @@ static void PollLoop(PRFileDesc *listenFD) //----------------------------------------------------------------------------- PRStatus -IPC_PlatformSendMsg(ipcClient *client, const ipcMessage *msg) +IPC_PlatformSendMsg(ipcClient *client, ipcMessage *msg) { LOG(("IPC_PlatformSendMsg\n")); // // must copy message onto send queue. // - client->EnqueueOutboundMsg(msg->Clone()); + client->EnqueueOutboundMsg(msg); // // since our Process method may have already been called, we must ensure diff --git a/modules/ipc/daemon/ipcdWin.cpp b/modules/ipc/daemon/ipcdWin.cpp index 8c6ad5894102..c869037abdc7 100644 --- a/modules/ipc/daemon/ipcdWin.cpp +++ b/modules/ipc/daemon/ipcdWin.cpp @@ -193,7 +193,7 @@ ProcessMsg(HWND hwnd, PRUint32 pid, const ipcMessage *msg) //----------------------------------------------------------------------------- PRStatus -IPC_PlatformSendMsg(ipcClient *client, const ipcMessage *msg) +IPC_PlatformSendMsg(ipcClient *client, ipcMessage *msg) { LOG(("IPC_SendMessageNow [clientID=%u clientPID=%u]\n", client->ID(), client->PID())); @@ -207,6 +207,7 @@ IPC_PlatformSendMsg(ipcClient *client, const ipcMessage *msg) SendMessage(client->Hwnd(), WM_COPYDATA, 0, (LPARAM) &cd); LOG((" done.\n")); + delete msg; return PR_SUCCESS; } diff --git a/modules/ipc/public/ipcIService.idl b/modules/ipc/public/ipcIService.idl index 594037f16bfc..41e508447075 100644 --- a/modules/ipc/public/ipcIService.idl +++ b/modules/ipc/public/ipcIService.idl @@ -41,12 +41,6 @@ interface nsISimpleEnumerator; interface ipcIMessageObserver; interface ipcIClientObserver; -%{C++ -#define IPC_SERVICE_STARTUP_CATEGORY "ipc-startup-category" -#define IPC_SERVICE_STARTUP_TOPIC "ipc-startup" -#define IPC_SERVICE_SHUTDOWN_TOPIC "ipc-shutdown" -%} - /** * the IPC service provides the means to communicate with an external IPC * daemon and/or other mozilla-based applications on the same physical system. @@ -78,23 +72,32 @@ interface ipcIClientObserver; interface ipcIService : nsISupports { /** - * returns the "client ID" assigned to this application by the IPC daemon. - * this number is the name given to our application for the current - * session. after a profile change, our client ID will change. + * returns the "client ID" assigned to this process by the IPC daemon. * * @throws NS_ERROR_NOT_AVAILABLE if no connection to the IPC daemon. */ readonly attribute unsigned long clientID; /** - * client aliases give the client a way to register itself under multiple - * names. for example, the mozilla browser might register itself under - * the name "mozilla", but it could also register itself under the aliases - * "browser", "mail", "news", "addrbook", and so on. aliases provide a - * simple mechanism for clients to discover other clients. + * returns the "primary client name" of this process. this value is taken + * from the pref "ipc.primary-client-name" at IPC service initialization + * time. */ - void addClientAlias(in ACString aAlias); - void removeClientAlias(in ACString aAlias); + readonly attribute ACString primaryClientName; + + /** + * this process can appear under several client names. use the following + * methods to add or remove names for this process. + * + * for example, the mozilla browser might have the primary name "mozilla", + * but it could also register itself under the names "browser", "mail", + * "news", "addrbook", etc. other IPC clients can then query the IPC + * daemon for the client named "mail" in order to talk with a mail program. + * + * An IPC client name resembles a XPCOM contract ID. + */ + void addClientName(in ACString aName); + void removeClientName(in ACString aName); /** * query info about a particular client given its client name. @@ -198,8 +201,17 @@ interface ipcIClientObserver : nsISupports */ void onClientStatus(in unsigned long aRequestToken, in unsigned long aStatus, + in unsigned long aClientID, in ipcIClientInfo aClientInfo); // XXX do we care about changes to the aliases and targets supported // by a client? if so, how should we pass this information up? }; + +%{C++ +#define IPC_SERVICE_STARTUP_CATEGORY "ipc-startup-category" +#define IPC_SERVICE_STARTUP_TOPIC "ipc-startup" +#define IPC_SERVICE_SHUTDOWN_TOPIC "ipc-shutdown" + +#define IPC_SERVICE_PREF_PRIMARY_CLIENT_NAME "ipc.primary-client-name" +%} diff --git a/modules/ipc/src/ipcService.cpp b/modules/ipc/src/ipcService.cpp index 2a9d36472324..bfc14400fadf 100644 --- a/modules/ipc/src/ipcService.cpp +++ b/modules/ipc/src/ipcService.cpp @@ -137,7 +137,8 @@ ipcService::Init() prefserv->GetBranch(nsnull, getter_AddRefs(prefbranch)); if (prefbranch) { nsXPIDLCString val; - prefbranch->GetCharPref("ipc.client-name", getter_Copies(val)); + prefbranch->GetCharPref(IPC_SERVICE_PREF_PRIMARY_CLIENT_NAME, + getter_Copies(val)); if (!val.IsEmpty()) appName = val; } @@ -161,6 +162,7 @@ ipcService::HandleQueryResult(const ipcMessage *rawMsg, PRBool succeeded) } PRUint32 cStatus; + PRUint32 cID; ipcClientInfo *info; if (succeeded) { @@ -172,13 +174,18 @@ ipcService::HandleQueryResult(const ipcMessage *rawMsg, PRBool succeeded) NS_ADDREF(info); info->Init(msg->ClientID(), query->mName); } + cID = msg->ClientID(); } else { cStatus = ipcIClientObserver::CLIENT_DOWN; + cID = 0; info = nsnull; } - query->mObserver->OnClientStatus(query->mReqToken, cStatus, info); + query->mObserver->OnClientStatus(query->mReqToken, + cStatus, + cID, + info); NS_IF_RELEASE(info); mQueryQ.DeleteFirst(); @@ -201,11 +208,18 @@ ipcService::GetClientID(PRUint32 *clientID) } NS_IMETHODIMP -ipcService::AddClientAlias(const nsACString &alias) +ipcService::GetPrimaryClientName(nsACString &primaryName) +{ + primaryName.Truncate(); // XXX implement me + return NS_OK; +} + +NS_IMETHODIMP +ipcService::AddClientName(const nsACString &name) { NS_ENSURE_TRUE(mTransport, NS_ERROR_NOT_INITIALIZED); - ipcMessage *msg = new ipcmMessageClientAddName(PromiseFlatCString(alias).get()); + ipcMessage *msg = new ipcmMessageClientAddName(PromiseFlatCString(name).get()); if (!msg) return NS_ERROR_OUT_OF_MEMORY; @@ -213,11 +227,11 @@ ipcService::AddClientAlias(const nsACString &alias) } NS_IMETHODIMP -ipcService::RemoveClientAlias(const nsACString &alias) +ipcService::RemoveClientName(const nsACString &name) { NS_ENSURE_TRUE(mTransport, NS_ERROR_NOT_INITIALIZED); - ipcMessage *msg = new ipcmMessageClientDelName(PromiseFlatCString(alias).get()); + ipcMessage *msg = new ipcmMessageClientDelName(PromiseFlatCString(name).get()); if (!msg) return NS_ERROR_OUT_OF_MEMORY; @@ -357,7 +371,7 @@ ipcService::OnConnectionLost() ipcClientQuery *query = mQueryQ.First(); query->mObserver->OnClientStatus(query->mReqToken, ipcIClientObserver::CLIENT_DOWN, - nsnull); + query->mID, nsnull); mQueryQ.DeleteFirst(); } diff --git a/modules/ipc/src/ipcService.h b/modules/ipc/src/ipcService.h index 84150aac5a8a..52d8d4fc0edf 100644 --- a/modules/ipc/src/ipcService.h +++ b/modules/ipc/src/ipcService.h @@ -82,11 +82,13 @@ class ipcClientQuery public: ipcClientQuery() : mNext(nsnull) + , mID(0) , mReqToken(0) { } ipcClientQuery *mNext; nsCString mName; + PRUint32 mID; PRUint32 mReqToken; nsCOMPtr mObserver; }; diff --git a/modules/ipc/src/ipcTransportWin.cpp b/modules/ipc/src/ipcTransportWin.cpp index a12b5f83274b..7f71a6c5b44a 100644 --- a/modules/ipc/src/ipcTransportWin.cpp +++ b/modules/ipc/src/ipcTransportWin.cpp @@ -336,6 +336,7 @@ ipcTransport::SendMsg_Internal(ipcMessage *msg) if (!PostMessage(ipcHwnd, IPC_WM_SEND_MESSAGE, 0, (LPARAM) msg)) { LOG((" PostMessage failed w/ error = %u\n", GetLastError())); + delete msg; return NS_ERROR_FAILURE; } return NS_OK; diff --git a/modules/ipc/test/TestIPC.cpp b/modules/ipc/test/TestIPC.cpp index eb575411838d..e222649f842d 100644 --- a/modules/ipc/test/TestIPC.cpp +++ b/modules/ipc/test/TestIPC.cpp @@ -103,22 +103,22 @@ public: NS_IMPL_ISUPPORTS1(myIpcClientObserver, ipcIClientObserver) NS_IMETHODIMP -myIpcClientObserver::OnClientStatus(PRUint32 aReqToken, PRUint32 aStatus, ipcIClientInfo *aClientInfo) +myIpcClientObserver::OnClientStatus(PRUint32 aReqToken, + PRUint32 aStatus, + PRUint32 aClientID, + ipcIClientInfo *aClientInfo) { printf("*** got client status [token=%u status=%u info=%p]\n", aReqToken, aStatus, (void *) aClientInfo); - if (aClientInfo) { - PRUint32 cID; - if (NS_SUCCEEDED(aClientInfo->GetID(&cID))) { + if (aClientID != 0) { + if (aClientInfo) { nsCAutoString cName; - if (NS_SUCCEEDED(aClientInfo->GetName(cName))) { - printf("*** name:%s --> ID:%u\n", cName.get(), cID); - - const char hello[] = "hello friend!"; - gIpcServ->SendMessage(cID, kTestTargetID, hello, sizeof(hello)); - } + if (NS_SUCCEEDED(aClientInfo->GetName(cName))) + printf("*** name:%s --> ID:%u\n", cName.get(), aClientID); } + const char hello[] = "hello friend!"; + gIpcServ->SendMessage(aClientID, kTestTargetID, hello, sizeof(hello)); } return NS_OK; @@ -164,7 +164,7 @@ int main(int argc, char **argv) nsCOMPtr prefbranch; prefserv->GetBranch(nsnull, getter_AddRefs(prefbranch)); if (prefbranch) - prefbranch->SetCharPref("ipc.client-name", argv[1]); + prefbranch->SetCharPref(IPC_SERVICE_PREF_PRIMARY_CLIENT_NAME, argv[1]); } } diff --git a/modules/ipc/testmodule/Makefile.in b/modules/ipc/testmodule/Makefile.in index 2c6a5fab250a..33bda313b95a 100644 --- a/modules/ipc/testmodule/Makefile.in +++ b/modules/ipc/testmodule/Makefile.in @@ -52,10 +52,6 @@ REQUIRES = xpcom \ CPPSRCS = TestModule.cpp -SHARED_LIBRARY_LIBS = \ - $(DIST)/lib/$(LIB_PREFIX)ipccom_s.$(LIB_SUFFIX) \ - $(NULL) - LOCAL_INCLUDES = \ -I$(srcdir)/../common \ $(NULL) diff --git a/modules/ipc/testmodule/TestModule.cpp b/modules/ipc/testmodule/TestModule.cpp index ae840201a8c4..001b1741015e 100644 --- a/modules/ipc/testmodule/TestModule.cpp +++ b/modules/ipc/testmodule/TestModule.cpp @@ -1,6 +1,5 @@ #include #include "ipcModuleUtil.h" -#include "ipcMessage.h" #define TEST_MODULE_ID \ { /* e628fc6e-a6a7-48c7-adba-f241d1128fb8 */ \ @@ -23,13 +22,15 @@ struct TestModule printf("*** TestModule::Shutdown\n"); } - static void HandleMsg(ipcClientHandle client, const ipcMessage *msg) + static void HandleMsg(ipcClientHandle client, + const nsID &target, + const void *data, + PRUint32 dataLen) { - printf("*** TestModule::HandleMsg [%s]\n", msg->Data()); - ipcMessage outMsg; + printf("*** TestModule::HandleMsg [%s]\n", (const char *) data); + static const char buf[] = "pong"; - outMsg.Init(kTestModuleID, buf, sizeof(buf)); - IPC_SendMsg(client, &outMsg); + IPC_SendMsg(client, kTestModuleID, buf, sizeof(buf)); } };