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.
This commit is contained in:
darin%netscape.com 2002-11-07 04:56:06 +00:00
Родитель 8f024f2ebc
Коммит 9834a0c693
19 изменённых файлов: 332 добавлений и 278 удалений

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

@ -59,7 +59,7 @@ ipcMessage::Reset()
}
ipcMessage *
ipcMessage::Clone()
ipcMessage::Clone() const
{
ipcMessage *clone = new ipcMessage();
if (!clone)

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

@ -98,7 +98,7 @@ public:
//
// create a copy of this message
//
ipcMessage *Clone();
ipcMessage *Clone() const;
//
// initialize message

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

@ -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

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

@ -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

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

@ -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:

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

@ -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;
}

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

@ -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__

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

@ -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__

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

@ -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; i<count; ++i)
AddModule(entries[i].target, entries[i].methods, PR_LoadLibrary(buf));
}
PR_UnloadLibrary(lib);
}
@ -117,13 +133,13 @@ InitModuleFromLib(const char *modulesDir, const char *fileName)
//
// search for a module registered under the specified id
//
ipcModule *
IPC_GetModuleByID(const nsID &id)
ipcModuleMethods *
IPC_GetModuleByTarget(const nsID &target)
{
for (int i=0; i<ipcModuleCount; ++i) {
ipcModuleRegEntry &entry = ipcModules[i];
if (entry.id.Equals(id))
return entry.module;
if (entry.target.Equals(target))
return entry.methods;
}
return NULL;
}
@ -134,8 +150,7 @@ IPC_InitModuleReg(const char *exePath)
//
// register built-in modules
//
ipcModule *module = IPC_GetCommandModule();
AddModule(module->ID(), 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);
}

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

@ -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__

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

@ -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; i<ipcClientCount; ++i) {
if (client->HasTarget(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) {

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

@ -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

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

@ -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__

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

@ -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;
}
//-----------------------------------------------------------------------------

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

@ -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__

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

@ -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;
}
//-----------------------------------------------------------------------------

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

@ -1,6 +0,0 @@
#ifndef ipcdWin_h__
#define ipcdWin_h__
void IPC_SendMessageNow(ipcClient *client, const ipcMessage *msg);
#endif // !ipcdWin_h__

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

@ -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) \

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

@ -1,9 +1,8 @@
#include <stdio.h>
#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;
}