further revisions following review w/ dougt

This commit is contained in:
darin%netscape.com 2002-11-21 07:57:09 +00:00
parent 16b085f9d6
commit 7d68ff1fe2
9 changed files with 89 additions and 110 deletions

View File

@ -51,6 +51,7 @@
#define IPC_SYNC_EVENT_NAME "Local\\MozillaIPCSyncEvent"
#define IPC_DAEMON_APP_NAME "mozipcd.exe"
#define IPC_PATH_SEP_CHAR '\\'
#define IPC_MODULES_DIR "ipc\\modules"
#define IPC_CLIENT_WINDOW_NAME_MAXLEN (sizeof(IPC_CLIENT_WINDOW_NAME_PREFIX) + 20)
@ -71,6 +72,7 @@ inline void IPC_GetClientWindowName(PRUint32 pid, char *buf)
#define IPC_DEFAULT_SOCKET_PATH "/tmp/.mozilla-ipc/ipcd"
#define IPC_DAEMON_APP_NAME "mozipcd"
#define IPC_PATH_SEP_CHAR '/'
#define IPC_MODULES_DIR "ipc/modules"
#endif

View File

@ -62,9 +62,9 @@ ipcClient::Init()
// every client must be able to handle IPCM messages.
mTargets.Append(IPCM_TARGET);
// XXX cleanup
// see ipcCommandModule for this:
//IPC_NotifyClientUp(this);
// although it is tempting to fire off the NotifyClientUp event at this
// time, we must wait until the client sends us a CLIENT_HELLO event.
// see ipcCommandModule::OnClientHello.
}
//
@ -141,27 +141,21 @@ ipcClient::DelTarget(const nsID &target)
// PR_POLL_WRITE - to wait for the client socket to become writable
//
int
ipcClient::Process(PRFileDesc *fd, int poll_flags)
ipcClient::Process(PRFileDesc *fd, int inFlags)
{
// XXX check if not read OR write
if ((poll_flags & PR_POLL_ERR) ||
(poll_flags & PR_POLL_HUP) ||
(poll_flags & PR_POLL_EXCEPT) ||
(poll_flags & PR_POLL_NVAL)) {
//
// expect Finalize method to be called next.
//
if (inFlags & (PR_POLL_ERR | PR_POLL_HUP |
PR_POLL_EXCEPT | PR_POLL_NVAL)) {
LOG(("client socket appears to have closed\n"));
return 0;
}
// always wait for more data
int ret_flags = PR_POLL_READ;
// expect to wait for more data
int outFlags = PR_POLL_READ;
if (poll_flags & PR_POLL_READ) {
if (inFlags & PR_POLL_READ) {
LOG(("client socket is now readable\n"));
char buf[1024]; // XXX 4k?
char buf[1024]; // XXX make this larger?
PRInt32 n;
// find out how much data is available for reading...
@ -176,8 +170,10 @@ ipcClient::Process(PRFileDesc *fd, int poll_flags)
PRUint32 nread;
PRBool complete;
// XXX check return value
mInMsg.ReadFrom(ptr, PRUint32(n), &nread, &complete);
if (mInMsg.ReadFrom(ptr, PRUint32(n), &nread, &complete) == PR_FAILURE) {
LOG(("message appears to be malformed; dropping client connection\n"));
return 0;
}
if (complete) {
IPC_DispatchMsg(this, &mInMsg);
@ -189,7 +185,7 @@ ipcClient::Process(PRFileDesc *fd, int poll_flags)
}
}
if (poll_flags & PR_POLL_WRITE) {
if (inFlags & PR_POLL_WRITE) {
LOG(("client socket is now writable\n"));
if (mOutMsgQ.First())
@ -197,9 +193,9 @@ ipcClient::Process(PRFileDesc *fd, int poll_flags)
}
if (mOutMsgQ.First())
ret_flags |= PR_POLL_WRITE;
outFlags |= PR_POLL_WRITE;
return ret_flags;
return outFlags;
}
//
@ -223,9 +219,10 @@ ipcClient::WriteMsgs(PRFileDesc *fd)
LOG(("wrote %d bytes\n", nw));
if (nw == bufLen)
if (nw == bufLen) {
mOutMsgQ.DeleteFirst();
// XXX mSendOffset = 0;
mSendOffset = 0;
}
else
mSendOffset += nw;
}

View File

@ -40,9 +40,6 @@
#include "nsID.h"
// XXX cruft
#define IPC_EXPORT extern "C" NS_EXPORT
class ipcMessage;
//
@ -122,6 +119,9 @@ struct ipcModuleMethods
//
#define IPC_DAEMON_METHODS_VERSION (1<<16) // 1.0
//
// enumeration functions may return FALSE to stop enumeration.
//
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);
@ -196,12 +196,6 @@ struct ipcDaemonMethods
//
PRUint32 (* getClientID) (ipcClientHandle client);
//
// returns the primary client name (NULL if the client did not specify a
// name). this is the first element returned via |enumClientNames|.
//
const char * (* getPrimaryClientName) (ipcClientHandle client);
//
// functions for inspecting the names and targets defined for a particular
// client instance.
@ -229,6 +223,10 @@ struct ipcModuleEntry
ipcModuleMethods *methods;
};
//-----------------------------------------------------------------------------
#define IPC_EXPORT extern "C" NS_EXPORT
//
// IPC_EXPORT int IPC_GetModules(const ipcDaemonMethods *, const ipcModuleEntry **);
//

View File

@ -107,7 +107,6 @@ InitModuleFromLib(const char *modulesDir, const char *fileName)
IPC_GetClientByName,
IPC_EnumClients,
IPC_GetClientID,
IPC_GetPrimaryClientName,
IPC_ClientHasName,
IPC_ClientHasTarget,
IPC_EnumClientNames,
@ -150,20 +149,6 @@ InitModuleFromLib(const char *modulesDir, const char *fileName)
// ipcModuleReg API
//-----------------------------------------------------------------------------
//
// search for a module registered under the specified id
//
ipcModuleMethods *
IPC_GetModuleByTarget(const nsID &target)
{
for (int i=0; i<ipcModuleCount; ++i) {
ipcModuleRegEntry &entry = ipcModules[i];
if (entry.target.Equals(target))
return entry.methods;
}
return NULL;
}
void
IPC_InitModuleReg(const char *exePath)
{
@ -173,8 +158,6 @@ IPC_InitModuleReg(const char *exePath)
//
// register plug-in modules
//
static const char relModDir[] = "ipc/modules"; // XXX fix slashes
char *p = PL_strrchr(exePath, IPC_PATH_SEP_CHAR);
if (p == NULL) {
LOG(("unexpected exe path\n"));
@ -182,13 +165,13 @@ IPC_InitModuleReg(const char *exePath)
}
int baseLen = p - exePath;
int finalLen = baseLen + 1 + sizeof(relModDir);
int finalLen = baseLen + 1 + sizeof(IPC_MODULES_DIR);
// 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));
memcpy(modulesDir + baseLen + 1, IPC_MODULES_DIR, sizeof(IPC_MODULES_DIR));
LOG(("loading libraries in %s\n", modulesDir));
//
@ -245,3 +228,17 @@ IPC_NotifyClientDown(ipcClient *client)
entry.methods->clientDown(client);
}
}
PRStatus
IPC_DispatchMsg(ipcClient *client, const nsID &target, const void *data, PRUint32 dataLen)
{
// dispatch message to every module registered under the given target.
for (int i=0; i<ipcModuleCount; ++i) {
ipcModuleRegEntry &entry = ipcModules[i];
if (entry.target.Equals(target)) {
if (entry.methods->handleMsg)
entry.methods->handleMsg(client, target, data, dataLen);
}
}
return PR_SUCCESS;
}

View File

@ -61,8 +61,6 @@ void IPC_ShutdownModuleReg();
//
ipcModuleMethods *IPC_GetModuleByTarget(const nsID &target);
// XXX "handle msg for target" instead
//
// notifies all modules of client connect/disconnect
//

View File

@ -46,7 +46,8 @@ extern const ipcDaemonMethods *gIPCDaemonMethods;
//-----------------------------------------------------------------------------
// inline wrapper functions
//
// XXX only usable inside module.. blah
// these functions may only be called by a module that uses the
// IPC_IMPL_GETMODULES macro.
//-----------------------------------------------------------------------------
inline PRStatus
@ -91,13 +92,6 @@ IPC_GetClientID(ipcClientHandle client)
return gIPCDaemonMethods->getClientID(client);
}
inline const char *
IPC_GetPrimaryClientName(ipcClientHandle client)
{
PR_ASSERT(gIPCDaemonMethods);
return gIPCDaemonMethods->getPrimaryClientName(client);
}
inline PRBool
IPC_ClientHasName(ipcClientHandle client, const char *name)
{
@ -143,14 +137,15 @@ IPC_SendMsg(PRUint32 clientID, const nsID &target, const void *data, PRUint32 da
// module factory macros
//-----------------------------------------------------------------------------
#define IPC_IMPL_GETMODULES(_modName, _modEntries) \
const ipcDaemonMethods *gIPCDaemonMethods; \
IPC_EXPORT int \
IPC_GetModules(const ipcDaemonMethods *dmeths, const ipcModuleEntry **ents) { \
/* XXX do version checking */ \
gIPCDaemonMethods = dmeths; \
*ents = _modEntries; \
return sizeof(_modEntries) / sizeof(ipcModuleEntry); \
#define IPC_IMPL_GETMODULES(_modName, _modEntries) \
const ipcDaemonMethods *gIPCDaemonMethods; \
IPC_EXPORT int \
IPC_GetModules(const ipcDaemonMethods *dmeths, \
const ipcModuleEntry **ents) { \
/* XXX do version checking */ \
gIPCDaemonMethods = dmeths; \
*ents = _modEntries; \
return sizeof(_modEntries) / sizeof(ipcModuleEntry); \
}
#endif // !ipcModuleUtil_h__

View File

@ -35,6 +35,8 @@
*
* ***** END LICENSE BLOCK ***** */
#include "prlog.h"
#include "ipcConfig.h"
#include "ipcLog.h"
#include "ipcMessage.h"
@ -48,8 +50,9 @@
PRStatus
IPC_DispatchMsg(ipcClient *client, const ipcMessage *msg)
{
// XXX assert args valid
//
PR_ASSERT(client);
PR_ASSERT(msg);
if (msg->Target().Equals(IPCM_TARGET)) {
IPCM_HandleMsg(client, msg);
return PR_SUCCESS;
@ -61,6 +64,8 @@ IPC_DispatchMsg(ipcClient *client, const ipcMessage *msg)
PRStatus
IPC_SendMsg(ipcClient *client, ipcMessage *msg)
{
PR_ASSERT(msg);
if (client == NULL) {
//
// broadcast
@ -82,21 +87,6 @@ IPC_SendMsg(ipcClient *client, ipcMessage *msg)
// 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.
// XXX methods should be |const|
ipcModuleMethods *methods = IPC_GetModuleByTarget(target);
if (methods) {
// XXX make sure handleMsg not null
methods->handleMsg(client, target, data, dataLen);
return PR_SUCCESS;
}
LOG(("no registered module; ignoring message\n"));
return PR_FAILURE;
}
PRStatus
IPC_SendMsg(ipcClient *client, const nsID &target, const void *data, PRUint32 dataLen)
{
@ -128,44 +118,40 @@ IPC_GetClientByName(const char *name)
void
IPC_EnumClients(ipcClientEnumFunc func, void *closure)
{
// XXX null check
// XXX check return val for STOP
for (int i = 0; i < ipcClientCount; ++i)
func(closure, &ipcClients[i], ipcClients[i].ID());
PR_ASSERT(func);
for (int i = 0; i < ipcClientCount; ++i) {
if (func(closure, &ipcClients[i], ipcClients[i].ID()) == PR_FALSE)
break;
}
}
PRUint32
IPC_GetClientID(ipcClient *client)
{
// XXX null check
PR_ASSERT(client);
return client->ID();
}
const char *
IPC_GetPrimaryClientName(ipcClient *client)
{
// XXX null check
// XXX eliminate
return client->PrimaryName();
}
PRBool
IPC_ClientHasName(ipcClient *client, const char *name)
{
// XXX null check
PR_ASSERT(client);
PR_ASSERT(name);
return client->HasName(name);
}
PRBool
IPC_ClientHasTarget(ipcClient *client, const nsID &target)
{
// XXX null check
PR_ASSERT(client);
return client->HasTarget(target);
}
void
IPC_EnumClientNames(ipcClient *client, ipcClientNameEnumFunc func, void *closure)
{
PR_ASSERT(client);
PR_ASSERT(func);
const ipcStringNode *node = client->Names();
while (node) {
if (func(closure, client, node->Value()) == PR_FALSE)
@ -177,6 +163,8 @@ IPC_EnumClientNames(ipcClient *client, ipcClientNameEnumFunc func, void *closure
void
IPC_EnumClientTargets(ipcClient *client, ipcClientTargetEnumFunc func, void *closure)
{
PR_ASSERT(client);
PR_ASSERT(func);
const ipcIDNode *node = client->Targets();
while (node) {
if (func(closure, client, node->Value()) == PR_FALSE)
@ -184,11 +172,3 @@ IPC_EnumClientTargets(ipcClient *client, ipcClientTargetEnumFunc func, void *clo
node = node->mNext;
}
}
// XXX remove
ipcClient *
IPC_GetClients(PRUint32 *count)
{
*count = (PRUint32) ipcClientCount;
return ipcClients;
}

View File

@ -54,7 +54,6 @@ 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);

View File

@ -59,6 +59,17 @@
#include "ipcdPrivate.h"
#include "ipcd.h"
void
IPC_Sleep(int seconds)
{
while (seconds > 0) {
LOG(("\rsleeping for %d seconds...", seconds));
PR_Sleep(PR_SecondsToInterval(1));
--seconds;
}
LOG(("\ndone sleeping\n"));
}
//-----------------------------------------------------------------------------
// ipc directory and locking...
//-----------------------------------------------------------------------------
@ -413,6 +424,8 @@ int main(int argc, char **argv)
end:
IPC_ShutdownModuleReg();
//IPC_Sleep(5);
// it is critical that we release the lock before closing the socket,
// otherwise, a client might launch another daemon that would be unable
// to acquire the lock and would then leave the client without a daemon.