From 56efc822efa1fb56e9bef75b0bc02c2a4201d9eb Mon Sep 17 00:00:00 2001 From: "darin%netscape.com" Date: Thu, 7 Nov 2002 04:56:06 +0000 Subject: [PATCH] major overhaul of daemon plug-in module story. modules now talk to the daemon through a table of function pointers. this greatly simplifies the linker magic required to allow the modules to talk with the daemon. git-svn-id: svn://10.0.0.236/trunk@133260 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/modules/ipc/common/ipcMessage.cpp | 2 +- mozilla/modules/ipc/common/ipcMessage.h | 2 +- mozilla/modules/ipc/daemon/Makefile.in | 19 +-- mozilla/modules/ipc/daemon/ipcClient.cpp | 34 +--- mozilla/modules/ipc/daemon/ipcClient.h | 15 +- .../modules/ipc/daemon/ipcCommandModule.cpp | 61 ++++--- mozilla/modules/ipc/daemon/ipcCommandModule.h | 4 +- mozilla/modules/ipc/daemon/ipcModule.h | 157 ++++++++++++++++-- mozilla/modules/ipc/daemon/ipcModuleReg.cpp | 61 ++++--- mozilla/modules/ipc/daemon/ipcModuleReg.h | 5 + mozilla/modules/ipc/daemon/ipcd.cpp | 64 +++---- mozilla/modules/ipc/daemon/ipcd.h | 90 ++-------- mozilla/modules/ipc/daemon/ipcdPrivate.h | 5 + mozilla/modules/ipc/daemon/ipcdUnix.cpp | 17 +- mozilla/modules/ipc/daemon/ipcdUnix.h | 10 -- mozilla/modules/ipc/daemon/ipcdWin.cpp | 5 +- mozilla/modules/ipc/daemon/ipcdWin.h | 6 - mozilla/modules/ipc/testmodule/Makefile.in | 4 - mozilla/modules/ipc/testmodule/TestModule.cpp | 49 +++--- 19 files changed, 332 insertions(+), 278 deletions(-) delete mode 100644 mozilla/modules/ipc/daemon/ipcdUnix.h delete mode 100644 mozilla/modules/ipc/daemon/ipcdWin.h diff --git a/mozilla/modules/ipc/common/ipcMessage.cpp b/mozilla/modules/ipc/common/ipcMessage.cpp index e50ae92d7c4..e4e097baac9 100644 --- a/mozilla/modules/ipc/common/ipcMessage.cpp +++ b/mozilla/modules/ipc/common/ipcMessage.cpp @@ -59,7 +59,7 @@ ipcMessage::Reset() } ipcMessage * -ipcMessage::Clone() +ipcMessage::Clone() const { ipcMessage *clone = new ipcMessage(); if (!clone) diff --git a/mozilla/modules/ipc/common/ipcMessage.h b/mozilla/modules/ipc/common/ipcMessage.h index be0bccb8322..d2e14047f0b 100644 --- a/mozilla/modules/ipc/common/ipcMessage.h +++ b/mozilla/modules/ipc/common/ipcMessage.h @@ -98,7 +98,7 @@ public: // // create a copy of this message // - ipcMessage *Clone(); + ipcMessage *Clone() const; // // initialize message diff --git a/mozilla/modules/ipc/daemon/Makefile.in b/mozilla/modules/ipc/daemon/Makefile.in index bd1bd6618b7..3769841f86c 100644 --- a/mozilla/modules/ipc/daemon/Makefile.in +++ b/mozilla/modules/ipc/daemon/Makefile.in @@ -63,7 +63,6 @@ PROGRAM = mozipcd$(BIN_SUFFIX) EXPORTS = \ ipcModule.h \ - ipcd.h \ $(NULL) LOCAL_INCLUDES = \ @@ -79,19 +78,19 @@ LIBS = \ $(NULL) # XXX -rdynamic is probably good for lots of other platforms -ifeq ($(OS_ARCH),Linux) -LIBS += -rdynamic -endif +#ifeq ($(OS_ARCH),Linux) +#LIBS += -rdynamic +#endif include $(topsrcdir)/config/rules.mk -DEFINES += -DIPC_DAEMON - -ifeq ($(OS_ARCH),WINNT) +#DEFINES += -DIPC_DAEMON +# +#ifeq ($(OS_ARCH),WINNT) # # need to install mozipcd.lib, which contains the symbols exported by the # daemon that modules will need to import. # -libs:: $(PROGRAM) - $(INSTALL) mozipcd.lib $(DIST)/lib -endif +#libs:: $(PROGRAM) +# $(INSTALL) mozipcd.lib $(DIST)/lib +#endif diff --git a/mozilla/modules/ipc/daemon/ipcClient.cpp b/mozilla/modules/ipc/daemon/ipcClient.cpp index 1e294650d9e..fdd07ec1852 100644 --- a/mozilla/modules/ipc/daemon/ipcClient.cpp +++ b/mozilla/modules/ipc/daemon/ipcClient.cpp @@ -43,11 +43,6 @@ #ifdef XP_UNIX #include "prio.h" -#include "ipcdUnix.h" -#endif - -#ifdef XP_WIN -#include "ipcdWin.h" #endif PRUint32 ipcClient::gLastID = 0; @@ -129,36 +124,8 @@ ipcClient::DelTarget(const nsID &target) mTargets.FindAndDelete(target); } -PRBool -ipcClient::EnqueueOutboundMsg(ipcMessage *msg) -{ - LOG(("enqueue outbound message\n")); - - if (!HasTarget(msg->Target())) { - LOG((" no registered message handler\n")); - delete msg; - return PR_FALSE; - } - -#ifdef XP_WIN - IPC_SendMessageNow(this, msg); - delete msg; -#endif - #ifdef XP_UNIX - mOutMsgQ.Append(msg); - // - // the message was successfully put on the queue... - // - // since our Process method may have already been called, we must ensure - // that the PR_POLL_WRITE flag is set. - // - IPC_ClientWritePending(this); -#endif - return PR_TRUE; -} -#ifdef XP_UNIX // // called to process a client socket // @@ -260,4 +227,5 @@ ipcClient::WriteMsgs(PRFileDesc *fd) return 0; } + #endif diff --git a/mozilla/modules/ipc/daemon/ipcClient.h b/mozilla/modules/ipc/daemon/ipcClient.h index 73e8927205c..9cc72448af3 100644 --- a/mozilla/modules/ipc/daemon/ipcClient.h +++ b/mozilla/modules/ipc/daemon/ipcClient.h @@ -78,15 +78,6 @@ public: // returns primary client name (the one specified in the "client hello" message) const char *PrimaryName() const { return mNames.First() ? mNames.First()->Value() : NULL; } - // - // returns TRUE if successfully enqueued. will return FALSE if client - // does not have a registered message handler for this message's target. - // - // on success or failure, this function takes ownership of |msg| and will - // delete it when appropriate. - // - PRBool EnqueueOutboundMsg(ipcMessage *msg); - #ifdef XP_WIN PRUint32 PID() const { return mPID; } void SetPID(PRUint32 pid) { mPID = pid; } @@ -109,6 +100,12 @@ public: // the socket is non-blocking. // int Process(PRFileDesc *sockFD, int pollFlags); + + // + // on success or failure, this function takes ownership of |msg| and will + // delete it when appropriate. + // + void EnqueueOutboundMsg(ipcMessage *msg) { mOutMsgQ.Append(msg); } #endif private: diff --git a/mozilla/modules/ipc/daemon/ipcCommandModule.cpp b/mozilla/modules/ipc/daemon/ipcCommandModule.cpp index e76f460b3dc..d44bdc3d682 100644 --- a/mozilla/modules/ipc/daemon/ipcCommandModule.cpp +++ b/mozilla/modules/ipc/daemon/ipcCommandModule.cpp @@ -45,25 +45,22 @@ #include "ipcd.h" #include "ipcm.h" -typedef const char * constCharPtr; - -class ipcCommandModule : public ipcModule +struct ipcCommandModule { -public: - typedef void (ipcCommandModule:: *MsgHandler)(ipcClient *, const ipcMessage *); + typedef void (* MsgHandler)(ipcClient *, const ipcMessage *); // // message handlers // - void OnPing(ipcClient *client, const ipcMessage *rawMsg) + static void OnPing(ipcClient *client, const ipcMessage *rawMsg) { LOG(("got PING\n")); IPC_SendMsg(client, new ipcmMessagePing()); } - void OnClientHello(ipcClient *client, const ipcMessage *rawMsg) + static void OnClientHello(ipcClient *client, const ipcMessage *rawMsg) { LOG(("got CLIENT_HELLO\n")); @@ -75,7 +72,7 @@ public: IPC_SendMsg(client, new ipcmMessageClientID(client->ID())); } - void OnClientAddName(ipcClient *client, const ipcMessage *rawMsg) + static void OnClientAddName(ipcClient *client, const ipcMessage *rawMsg) { LOG(("got CLIENT_ADD_NAME\n")); @@ -85,7 +82,7 @@ public: client->AddName(name); } - void OnClientDelName(ipcClient *client, const ipcMessage *rawMsg) + static void OnClientDelName(ipcClient *client, const ipcMessage *rawMsg) { LOG(("got CLIENT_DEL_NAME\n")); @@ -95,7 +92,7 @@ public: client->DelName(name); } - void OnClientAddTarget(ipcClient *client, const ipcMessage *rawMsg) + static void OnClientAddTarget(ipcClient *client, const ipcMessage *rawMsg) { LOG(("got CLIENT_ADD_TARGET\n")); @@ -103,7 +100,7 @@ public: client->AddTarget(msg->Target()); } - void OnClientDelTarget(ipcClient *client, const ipcMessage *rawMsg) + static void OnClientDelTarget(ipcClient *client, const ipcMessage *rawMsg) { LOG(("got CLIENT_DEL_TARGET\n")); @@ -111,7 +108,7 @@ public: client->DelTarget(msg->Target()); } - void OnQueryClientByName(ipcClient *client, const ipcMessage *rawMsg) + static void OnQueryClientByName(ipcClient *client, const ipcMessage *rawMsg) { LOG(("got QUERY_CLIENT_BY_NAME\n")); @@ -127,7 +124,7 @@ public: } } - void OnForward(ipcClient *client, const ipcMessage *rawMsg) + static void OnForward(ipcClient *client, const ipcMessage *rawMsg) { LOG(("got FORWARD\n")); @@ -145,31 +142,26 @@ public: // ipcModule interface impl // - void Shutdown() + static void Shutdown() { } - const nsID &ID() - { - return IPCM_TARGET; - } - - void HandleMsg(ipcClient *client, const ipcMessage *rawMsg) + static void HandleMsg(ipcClient *client, const ipcMessage *rawMsg) { static MsgHandler handlers[] = { - &ipcCommandModule::OnPing, + OnPing, NULL, // ERROR - &ipcCommandModule::OnClientHello, + OnClientHello, NULL, // CLIENT_ID NULL, // CLIENT_INFO - &ipcCommandModule::OnClientAddName, - &ipcCommandModule::OnClientDelName, - &ipcCommandModule::OnClientAddTarget, - &ipcCommandModule::OnClientDelTarget, - &ipcCommandModule::OnQueryClientByName, + OnClientAddName, + OnClientDelName, + OnClientAddTarget, + OnClientDelTarget, + OnQueryClientByName, NULL, // QUERY_CLIENT_INFO - &ipcCommandModule::OnForward, + OnForward, }; int type = IPCM_GetMsgType(rawMsg); @@ -178,14 +170,19 @@ public: if (type < IPCM_MSG_TYPE_UNKNOWN) { if (handlers[type]) { MsgHandler handler = handlers[type]; - (this->*handler)(client, rawMsg); + handler(client, rawMsg); } } } }; -ipcModule *IPC_GetCommandModule() +ipcModuleMethods *IPC_GetCommandModuleMethods() { - static ipcCommandModule module; - return &module; + static ipcModuleMethods methods = + { + IPC_MODULE_METHODS_VERSION, + ipcCommandModule::Shutdown, + ipcCommandModule::HandleMsg + }; + return &methods; } diff --git a/mozilla/modules/ipc/daemon/ipcCommandModule.h b/mozilla/modules/ipc/daemon/ipcCommandModule.h index e2e9121e1a4..9ffede61428 100644 --- a/mozilla/modules/ipc/daemon/ipcCommandModule.h +++ b/mozilla/modules/ipc/daemon/ipcCommandModule.h @@ -38,8 +38,8 @@ #ifndef ipcCommandModule_h__ #define ipcCommandModule_h__ -#include "ipcm.h" +#include "ipcm.h" // for IPCM_TARGET -class ipcModule *IPC_GetCommandModule(); +struct ipcModuleMethods *IPC_GetCommandModuleMethods(); #endif // !ipcCommandModule_h__ diff --git a/mozilla/modules/ipc/daemon/ipcModule.h b/mozilla/modules/ipc/daemon/ipcModule.h index e4479d68513..56f7ef29638 100644 --- a/mozilla/modules/ipc/daemon/ipcModule.h +++ b/mozilla/modules/ipc/daemon/ipcModule.h @@ -40,28 +40,42 @@ #include "nsID.h" +#define IPC_EXPORT extern "C" NS_EXPORT + class ipcMessage; -class ipcClient; + +// +// a client handle is used to efficiently reference a client instance object +// used by the daemon to represent a connection with a particular client app. +// +// modules should treat it as an opaque type. +// +typedef class ipcClient *ipcClientHandle; //----------------------------------------------------------------------------- -// abstract module class +// interface implemented by the module: //----------------------------------------------------------------------------- -class ipcModule +// +// the version of ipcModuleMethods data structure. +// +#define IPC_MODULE_METHODS_VERSION (1<<16) // 1.0 + +// +// each module defines the following structure: +// +struct ipcModuleMethods { -public: // - // called when this module will no longer be accessed. if this module was - // allocated on the heap, then it can be free'd. + // this field holds the version of the data structure, which is always the + // value of IPC_MODULE_METHODS_VERSION against which the module was built. // - virtual void Shutdown() = 0; + PRUint32 version; // - // called to determine the ID of this module. the ID of a module - // indicates the "message target" for which it will be registered - // as a handler. + // called when this module will no longer be accessed. // - virtual const nsID &ID() = 0; + void (* shutdown) (void); // // called when a new message arrives for this module. @@ -78,18 +92,125 @@ public: // msg - the message sent from the client. the target of this message // matches the ID of this module. // - virtual void HandleMsg(ipcClient *client, const ipcMessage *msg) = 0; + void (* handleMsg) (ipcClientHandle client, const ipcMessage *msg); +}; + +//----------------------------------------------------------------------------- +// interface implemented by the daemon: +//----------------------------------------------------------------------------- + +// +// the version of ipcDaemonMethods data structure. +// +#define IPC_DAEMON_METHODS_VERSION (1<<16) // 1.0 + +typedef PRBool (* ipcClientEnumFunc) (void *closure, ipcClientHandle client, PRUint32 clientID); +typedef PRBool (* ipcClientNameEnumFunc) (void *closure, ipcClientHandle client, const char *name); +typedef PRBool (* ipcClientTargetEnumFunc) (void *closure, ipcClientHandle client, const nsID &target); + +// +// the daemon provides the following structure: +// +struct ipcDaemonMethods +{ + PRUint32 version; + + // + // called to send a message to another module. + // + // params: + // client - identifies the client from which this message originated. + // msg - the message to dispatch. + // + // 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); + + // + // called to send a message to a particular client or to broadcast a + // message to all clients. + // + // params: + // client - if null, then broadcast message to all clients. otherwise, + // send message to the client specified. + // msg - the message to send. + // + // returns: + // PR_SUCCESS if message was sent (or queued up to be sent later). + // 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); + + // + // called to lookup a client handle given its client ID. each client has + // a unique ID. + // + ipcClientHandle (* getClientByID) (PRUint32 clientID); + + // + // called to lookup a client by name or alias. names are not necessary + // unique to individual clients. this function returns the client first + // registered under the given name. + // + ipcClientHandle (* getClientByName) (const char *name); + + // + // called to enumerate all clients. + // + void (* enumClients) (ipcClientEnumFunc func, void *closure); + + // + // returns the client ID of the specified client. + // + PRUint32 (* getClientID) (ipcClientHandle client); + + // + // returns the primary client name (NULL if the client did not specify a name). + // this is the name specified by the client in its "client hello" message. + // + const char * (* getPrimaryClientName) (ipcClientHandle client); + + // + // functions for inspecting the names and targets defined for a particular + // client instance. + // + PRBool (* clientHasName) (ipcClientHandle client, const char *name); + PRBool (* clientHasTarget) (ipcClientHandle client, const nsID &target); + void (* enumClientNames) (ipcClientHandle client, ipcClientNameEnumFunc func, void *closure); + void (* enumClientTargets) (ipcClientHandle client, ipcClientTargetEnumFunc func, void *closure); +}; + +//----------------------------------------------------------------------------- +// interface exported by a DSO implementing one or more modules: +//----------------------------------------------------------------------------- + +struct ipcModuleEntry +{ + // + // identifies the message target of this module. + // + nsID target; + + // + // module methods + // + ipcModuleMethods *methods; }; // -// factory method signature for DLLs, which may define more than one ipcModule -// implementation. the DLL must export the following symbol: +// IPC_EXPORT int IPC_GetModules(ipcDaemonMethods *, ipcModuleEntry **); // -// extern "C" ipcModule **IPC_GetModuleList(); +// params: +// methods - the daemon's methods +// entries - the module entries defined by the DSO // -// return: -// null terminated array of modules. +// returns: +// length of the |entries| array. // -typedef ipcModule ** (*ipcGetModuleListFunc)(void); +typedef int (* ipcGetModulesFunc) (ipcDaemonMethods *methods, ipcModuleEntry **entries); #endif // !ipcModule_h__ diff --git a/mozilla/modules/ipc/daemon/ipcModuleReg.cpp b/mozilla/modules/ipc/daemon/ipcModuleReg.cpp index b91c7a78027..f410d6444d4 100644 --- a/mozilla/modules/ipc/daemon/ipcModuleReg.cpp +++ b/mozilla/modules/ipc/daemon/ipcModuleReg.cpp @@ -51,9 +51,9 @@ struct ipcModuleRegEntry { - nsID id; - ipcModule *module; - PRLibrary *lib; + nsID target; + ipcModuleMethods *methods; + PRLibrary *lib; }; #define IPC_MAX_MODULE_COUNT 64 @@ -62,15 +62,15 @@ static ipcModuleRegEntry ipcModules[IPC_MAX_MODULE_COUNT]; static int ipcModuleCount; static PRStatus -AddModule(const nsID &id, ipcModule *module, PRLibrary *lib) +AddModule(const nsID &target, ipcModuleMethods *methods, PRLibrary *lib) { if (ipcModuleCount == IPC_MAX_MODULE_COUNT) { LOG(("too many modules!\n")); return PR_FAILURE; } - ipcModules[ipcModuleCount].id = id; - ipcModules[ipcModuleCount].module = module; + ipcModules[ipcModuleCount].target = target; + ipcModules[ipcModuleCount].methods = methods; ipcModules[ipcModuleCount].lib = lib; ++ipcModuleCount; @@ -82,6 +82,22 @@ InitModuleFromLib(const char *modulesDir, const char *fileName) { LOG(("InitModuleFromLib [%s]\n", fileName)); + static ipcDaemonMethods gDaemonMethods = + { + IPC_DAEMON_METHODS_VERSION, + IPC_DispatchMsg, + IPC_SendMsg, + IPC_GetClientByID, + IPC_GetClientByName, + IPC_EnumClients, + IPC_GetClientID, + IPC_GetPrimaryClientName, + IPC_ClientHasName, + IPC_ClientHasTarget, + IPC_EnumClientNames, + IPC_EnumClientTargets + }; + int dLen = strlen(modulesDir); int fLen = strlen(fileName); @@ -93,16 +109,16 @@ InitModuleFromLib(const char *modulesDir, const char *fileName) PRLibrary *lib = PR_LoadLibrary(buf); if (lib) { - ipcGetModuleListFunc func = - (ipcGetModuleListFunc) PR_FindFunctionSymbol(lib, "IPC_GetModuleList"); + ipcGetModulesFunc func = + (ipcGetModulesFunc) PR_FindFunctionSymbol(lib, "IPC_GetModules"); + + LOG((" func=%p\n", (void*) func)); + if (func) { - ipcModule **modules = func(); - if (modules) { - while (*modules) { - AddModule((*modules)->ID(), *modules, PR_LoadLibrary(buf)); - ++modules; - } - } + ipcModuleEntry *entries = NULL; + int count = func(&gDaemonMethods, &entries); + for (int i=0; iID(), module, NULL); + AddModule(IPCM_TARGET, IPC_GetCommandModuleMethods(), NULL); // // register plug-in modules @@ -186,8 +201,8 @@ IPC_ShutdownModuleReg() // for (int i = ipcModuleCount - 1; i >= 0; --i) { ipcModuleRegEntry &entry = ipcModules[i]; - if (entry.module) - entry.module->Shutdown(); + if (entry.methods) + entry.methods->shutdown(); if (entry.lib) PR_UnloadLibrary(entry.lib); } diff --git a/mozilla/modules/ipc/daemon/ipcModuleReg.h b/mozilla/modules/ipc/daemon/ipcModuleReg.h index 766d3e085f8..eda26a415ec 100644 --- a/mozilla/modules/ipc/daemon/ipcModuleReg.h +++ b/mozilla/modules/ipc/daemon/ipcModuleReg.h @@ -54,4 +54,9 @@ void IPC_InitModuleReg(const char *exePath); // void IPC_ShutdownModuleReg(); +// +// returns the ipcModuleMethods for the given target. +// +ipcModuleMethods *IPC_GetModuleByTarget(const nsID &target); + #endif // !ipcModuleReg_h__ diff --git a/mozilla/modules/ipc/daemon/ipcd.cpp b/mozilla/modules/ipc/daemon/ipcd.cpp index 669d607ab46..0bae6c8e563 100644 --- a/mozilla/modules/ipc/daemon/ipcd.cpp +++ b/mozilla/modules/ipc/daemon/ipcd.cpp @@ -52,9 +52,9 @@ PRStatus IPC_DispatchMsg(ipcClient *client, const ipcMessage *msg) { // lookup handler for this message's topic and forward message to it. - ipcModule *module = IPC_GetModuleByID(msg->Target()); - if (module) { - module->HandleMsg(client, msg); + ipcModuleMethods *methods = IPC_GetModuleByTarget(msg->Target()); + if (methods) { + methods->handleMsg(client, msg); return PR_SUCCESS; } LOG(("no registered module; ignoring message\n")); @@ -62,34 +62,23 @@ IPC_DispatchMsg(ipcClient *client, const ipcMessage *msg) } PRStatus -IPC_SendMsg(ipcClient *client, ipcMessage *msg) +IPC_SendMsg(ipcClient *client, const ipcMessage *msg) { if (client == NULL) { - int i; // - // walk clients array + // broadcast // - for (i = 0; i < ipcClientCount; ++i) - IPC_SendMsg(&ipcClients[i], msg->Clone()); - - // send to last client w/o cloning to avoid extra malloc - IPC_SendMsg(&ipcClients[i], msg); + for (int i=0; iHasTarget(msg->Target())) + IPC_PlatformSendMsg(&ipcClients[i], msg); + } + return PR_SUCCESS; } - else - client->EnqueueOutboundMsg(msg); - return PR_SUCCESS; -} - -PRUint32 -IPC_GetClientID(ipcClient *client) -{ - return client->ID(); -} - -const char * -IPC_GetPrimaryClientName(ipcClient *client) -{ - return client->PrimaryName(); + if (!client->HasTarget(msg->Target())) { + LOG(("no registered message handler\n")); + return PR_FAILURE; + } + return IPC_PlatformSendMsg(client, msg); } ipcClient * @@ -114,6 +103,25 @@ IPC_GetClientByName(const char *name) return NULL; } +void +IPC_EnumClients(ipcClientEnumFunc func, void *closure) +{ + for (int i = 0; i < ipcClientCount; ++i) + func(closure, &ipcClients[i], ipcClients[i].ID()); +} + +PRUint32 +IPC_GetClientID(ipcClient *client) +{ + return client->ID(); +} + +const char * +IPC_GetPrimaryClientName(ipcClient *client) +{ + return client->PrimaryName(); +} + PRBool IPC_ClientHasName(ipcClient *client, const char *name) { @@ -127,7 +135,7 @@ IPC_ClientHasTarget(ipcClient *client, const nsID &target) } void -IPC_EnumerateClientNames(ipcClient *client, ipcClientNameEnumFunc func, void *closure) +IPC_EnumClientNames(ipcClient *client, ipcClientNameEnumFunc func, void *closure) { const ipcStringNode *node = client->Names(); while (node) { @@ -138,7 +146,7 @@ IPC_EnumerateClientNames(ipcClient *client, ipcClientNameEnumFunc func, void *cl } void -IPC_EnumerateClientTargets(ipcClient *client, ipcClientTargetEnumFunc func, void *closure) +IPC_EnumClientTargets(ipcClient *client, ipcClientTargetEnumFunc func, void *closure) { const ipcIDNode *node = client->Targets(); while (node) { diff --git a/mozilla/modules/ipc/daemon/ipcd.h b/mozilla/modules/ipc/daemon/ipcd.h index 64d80ecbaa0..55f388360ab 100644 --- a/mozilla/modules/ipc/daemon/ipcd.h +++ b/mozilla/modules/ipc/daemon/ipcd.h @@ -40,84 +40,24 @@ #include "ipcModule.h" -#define IPC_EXPORT extern "C" NS_EXPORT -#define IPC_IMPORT extern "C" NS_IMPORT - -#ifdef IPC_DAEMON -#define IPC_API IPC_EXPORT -#else -#define IPC_API IPC_IMPORT -#endif - -class ipcClient; -class ipcMessage; - //----------------------------------------------------------------------------- -// IPC daemon API +// IPC daemon methods (see struct ipcDaemonMethods) +// +// these functions may only be called directly from within the daemon. plug-in +// modules must access these through the ipcDaemonMethods structure. //----------------------------------------------------------------------------- -// -// IPC_DispatchMsg -// -// params: -// client - identifies the client from which this message originated. -// msg - the message received. this function does not modify |msg|, -// and ownership stays with the caller. -// -IPC_API PRStatus IPC_DispatchMsg(ipcClient *client, const ipcMessage *msg); - -// -// IPC_SendMsg -// -// params: -// client - identifies the client that should receive the message. -// if null, then the message is broadcast to all clients. -// msg - the message to be sent. this function subsumes -// ownership of the message. the caller must not attempt -// to access |msg| after this function returns. -// -IPC_API PRStatus IPC_SendMsg(ipcClient *client, ipcMessage *msg); - -// -// returns the client ID dynamically generated for the given client. -// -IPC_API PRUint32 IPC_GetClientID(ipcClient *client); - -// -// returns the primary client name (NULL if the client did not specify a name). -// this is the name specified by the client in its "client hello" message. -// -IPC_API const char *IPC_GetPrimaryClientName(ipcClient *client); - -// -// client lookup functions -// -IPC_API ipcClient *IPC_GetClientByID(PRUint32 id); -IPC_API ipcClient *IPC_GetClientByName(const char *name); - -// -// functions for inspecting the names and targets defined for a particular -// client instance. -// -IPC_API PRBool IPC_ClientHasName(ipcClient *client, const char *name); -IPC_API PRBool IPC_ClientHasTarget(ipcClient *client, const nsID &target); - -// return PR_FALSE to end enumeration -typedef PRBool (* ipcClientNameEnumFunc)(void *closure, ipcClient *client, const char *name); -typedef PRBool (* ipcClientTargetEnumFunc)(void *closure, ipcClient *client, const nsID &target); - -IPC_API void IPC_EnumerateClientNames(ipcClient *client, ipcClientNameEnumFunc func, void *closure); -IPC_API void IPC_EnumerateClientTargets(ipcClient *client, ipcClientTargetEnumFunc func, void *closure); - -// -// return array of all clients, length equal to |count|. -// -IPC_API ipcClient *IPC_GetClients(PRUintn *count); - -// -// returns the ipcModule object registered under the given module ID. -// -IPC_API ipcModule *IPC_GetModuleByID(const nsID &moduleID); +PRStatus IPC_DispatchMsg (ipcClientHandle client, const ipcMessage *msg); +PRStatus IPC_SendMsg (ipcClientHandle client, const ipcMessage *msg); +ipcClientHandle IPC_GetClientByID (PRUint32 id); +ipcClientHandle IPC_GetClientByName (const char *name); +void IPC_EnumClients (ipcClientEnumFunc func, void *closure); +PRUint32 IPC_GetClientID (ipcClientHandle client); +const char *IPC_GetPrimaryClientName (ipcClientHandle client); +PRBool IPC_ClientHasName (ipcClientHandle client, const char *name); +PRBool IPC_ClientHasTarget (ipcClientHandle client, const nsID &target); +void IPC_EnumClientNames (ipcClientHandle client, ipcClientNameEnumFunc func, void *closure); +void IPC_EnumClientTargets (ipcClientHandle client, ipcClientTargetEnumFunc func, void *closure); //----------------------------------------------------------------------------- // inline helpers diff --git a/mozilla/modules/ipc/daemon/ipcdPrivate.h b/mozilla/modules/ipc/daemon/ipcdPrivate.h index f770ef31f3d..34c3237fc15 100644 --- a/mozilla/modules/ipc/daemon/ipcdPrivate.h +++ b/mozilla/modules/ipc/daemon/ipcdPrivate.h @@ -15,4 +15,9 @@ class ipcClient; extern ipcClient *ipcClients; extern int ipcClientCount; +// +// platform specific send message function. +// +PRStatus IPC_PlatformSendMsg(ipcClient *client, const ipcMessage *msg); + #endif // !ipcdPrivate_h__ diff --git a/mozilla/modules/ipc/daemon/ipcdUnix.cpp b/mozilla/modules/ipc/daemon/ipcdUnix.cpp index df340029afb..932eb957d57 100644 --- a/mozilla/modules/ipc/daemon/ipcdUnix.cpp +++ b/mozilla/modules/ipc/daemon/ipcdUnix.cpp @@ -339,11 +339,24 @@ static void PollLoop(PRFileDesc *listenFD) //----------------------------------------------------------------------------- -void -IPC_ClientWritePending(ipcClient *client) +PRStatus +IPC_PlatformSendMsg(ipcClient *client, const ipcMessage *msg) { + LOG(("IPC_PlatformSendMsg\n")); + + // + // must copy message onto send queue. + // + client->EnqueueOutboundMsg(msg->Clone()); + + // + // since our Process method may have already been called, we must ensure + // that the PR_POLL_WRITE flag is set. + // int clientIndex = client - ipcClientArray; ipcPollList[clientIndex].in_flags |= PR_POLL_WRITE; + + return PR_SUCCESS; } //----------------------------------------------------------------------------- diff --git a/mozilla/modules/ipc/daemon/ipcdUnix.h b/mozilla/modules/ipc/daemon/ipcdUnix.h deleted file mode 100644 index edc41670cef..00000000000 --- a/mozilla/modules/ipc/daemon/ipcdUnix.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef ipcdUnix_h__ -#define ipcdUnix_h__ - -// -// called by the ipcClient code to ensure that the client socket connection -// has PR_POLL_WRITE set. -// -void IPC_ClientWritePending(ipcClient *); - -#endif // !ipcdUnix_h__ diff --git a/mozilla/modules/ipc/daemon/ipcdWin.cpp b/mozilla/modules/ipc/daemon/ipcdWin.cpp index 930b9fe3b55..f5c20f6fae1 100644 --- a/mozilla/modules/ipc/daemon/ipcdWin.cpp +++ b/mozilla/modules/ipc/daemon/ipcdWin.cpp @@ -178,7 +178,7 @@ ProcessMsg(HWND hwnd, PRUint32 pid, const ipcMessage *msg) //----------------------------------------------------------------------------- void -IPC_SendMessageNow(ipcClient *client, const ipcMessage *msg) +IPC_PlatformSendMsg(ipcClient *client, const ipcMessage *msg) { LOG(("IPC_SendMessageNow [clientID=%u clientPID=%u]\n", client->ID(), client->PID())); @@ -188,11 +188,12 @@ IPC_SendMessageNow(ipcClient *client, const ipcMessage *msg) cd.cbData = (DWORD) msg->MsgLen(); cd.lpData = (PVOID) msg->MsgBuf(); - LOG(("calling SendMessage...\n")); SendMessageA(client->Hwnd(), WM_COPYDATA, 0, (LPARAM) &cd); // SendMessageA(hwnd, WM_COPYDATA, (WPARAM) ipcHwnd, (LPARAM) &cd); LOG((" done.\n")); + + return PR_SUCCESS; } //----------------------------------------------------------------------------- diff --git a/mozilla/modules/ipc/daemon/ipcdWin.h b/mozilla/modules/ipc/daemon/ipcdWin.h deleted file mode 100644 index 579aebe58cc..00000000000 --- a/mozilla/modules/ipc/daemon/ipcdWin.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef ipcdWin_h__ -#define ipcdWin_h__ - -void IPC_SendMessageNow(ipcClient *client, const ipcMessage *msg); - -#endif // !ipcdWin_h__ diff --git a/mozilla/modules/ipc/testmodule/Makefile.in b/mozilla/modules/ipc/testmodule/Makefile.in index 2145079e264..cacb668e170 100644 --- a/mozilla/modules/ipc/testmodule/Makefile.in +++ b/mozilla/modules/ipc/testmodule/Makefile.in @@ -61,10 +61,6 @@ LOCAL_INCLUDES = \ -I$(srcdir)/../common \ $(NULL) -ifeq ($(MOZ_WIDGET_TOOLKIT),windows) -EXTRA_DSO_LIBS = mozipcd -endif - EXTRA_DSO_LDOPTS = \ $(LIBS_DIR) \ $(NSPR_LIBS) \ diff --git a/mozilla/modules/ipc/testmodule/TestModule.cpp b/mozilla/modules/ipc/testmodule/TestModule.cpp index 8045f82462d..e87eea535e6 100644 --- a/mozilla/modules/ipc/testmodule/TestModule.cpp +++ b/mozilla/modules/ipc/testmodule/TestModule.cpp @@ -1,9 +1,8 @@ #include #include "ipcModule.h" #include "ipcMessage.h" -#include "ipcd.h" -IPC_EXPORT ipcModule **IPC_GetModuleList(); +IPC_EXPORT int IPC_GetModules(ipcDaemonMethods *, ipcModuleEntry **); static const nsID TestModuleID = { /* e628fc6e-a6a7-48c7-adba-f241d1128fb8 */ @@ -13,38 +12,44 @@ static const nsID TestModuleID = {0xad, 0xba, 0xf2, 0x41, 0xd1, 0x12, 0x8f, 0xb8} }; -class TestModule : public ipcModule +static ipcDaemonMethods *gDaemonMethods; + +struct TestModule { -public: - void Shutdown() + static void Shutdown() { printf("*** TestModule::Shutdown\n"); } - const nsID &ID() - { - printf("*** TestModule::ID\n"); - return TestModuleID; - } - - void HandleMsg(ipcClient *client, const ipcMessage *msg) + static void HandleMsg(ipcClientHandle client, const ipcMessage *msg) { printf("*** TestModule::HandleMsg [%s]\n", msg->Data()); - ipcMessage *outMsg = new ipcMessage(); + ipcMessage outMsg; static const char buf[] = "pong"; - outMsg->Init(TestModuleID, buf, sizeof(buf)); - IPC_SendMsg(client, outMsg); + outMsg.Init(TestModuleID, buf, sizeof(buf)); + gDaemonMethods->sendMsg(client, &outMsg); } }; -ipcModule ** -IPC_GetModuleList() +int +IPC_GetModules(ipcDaemonMethods *daemonMeths, ipcModuleEntry **entries) { - static TestModule testMod; - static ipcModule *modules[2]; + printf("*** testmodule: IPC_GetModules\n"); - modules[0] = &testMod; - modules[1] = NULL; + static ipcModuleMethods methods = + { + IPC_MODULE_METHODS_VERSION, + TestModule::Shutdown, + TestModule::HandleMsg + }; + static ipcModuleEntry moduleEntry = + { + TestModuleID, + &methods + }; - return modules; + gDaemonMethods = daemonMeths; + + *entries = &moduleEntry; + return 1; }