diff --git a/mozilla/modules/ipc/build/Makefile.in b/mozilla/modules/ipc/build/Makefile.in index 9bef60b9423..155eef2c161 100644 --- a/mozilla/modules/ipc/build/Makefile.in +++ b/mozilla/modules/ipc/build/Makefile.in @@ -63,7 +63,7 @@ SHARED_LIBRARY_LIBS = \ LOCAL_INCLUDES = \ -I$(srcdir)/../src \ - -I$(srcdir)/../util \ + -I$(srcdir)/../common \ $(NULL) EXTRA_DSO_LDOPTS = \ diff --git a/mozilla/modules/ipc/common/Makefile.in b/mozilla/modules/ipc/common/Makefile.in index a9117e6374c..74da59ec62b 100644 --- a/mozilla/modules/ipc/common/Makefile.in +++ b/mozilla/modules/ipc/common/Makefile.in @@ -53,8 +53,8 @@ REQUIRES = \ $(NULL) CPPSRCS = \ + ipcLog.cpp \ ipcMessage.cpp \ - ipcMessageQ.cpp \ ipcMessagePrimitives.cpp \ ipcm.cpp diff --git a/mozilla/modules/ipc/common/ipcLog.cpp b/mozilla/modules/ipc/common/ipcLog.cpp new file mode 100644 index 00000000000..b2d1de37e03 --- /dev/null +++ b/mozilla/modules/ipc/common/ipcLog.cpp @@ -0,0 +1,46 @@ +#ifdef XP_UNIX +#include +#include +#endif + +#include "prenv.h" +#include "prprf.h" +#include "plstr.h" +#include "ipcLog.h" + +PRBool ipcLogEnabled; +char ipcLogPrefix[10]; + +void +IPC_InitLog(const char *prefix) +{ + if (PR_GetEnv("IPC_LOG_ENABLE")) { + ipcLogEnabled = PR_TRUE; + PL_strncpyz(ipcLogPrefix, prefix, sizeof(ipcLogPrefix)); + } +} + +void +IPC_Log(const char *fmt, ... ) +{ + va_list ap; + va_start(ap, fmt); + PRUint32 nb; + char buf[512]; + + if (ipcLogPrefix[0]) +#ifdef XP_UNIX + nb = PR_snprintf(buf, sizeof(buf), "[%u] %s ", getpid(), ipcLogPrefix); +#else + nb = PR_snprintf(buf, sizeof(buf), "%s ", ipcLogPrefix); +#endif + else + nb = 0; + + PR_vsnprintf(buf + nb, sizeof(buf) - nb, fmt, ap); + buf[sizeof(buf) - 1] = '\0'; + + printf("%s", buf); + + va_end(ap); +} diff --git a/mozilla/modules/ipc/common/ipcLog.h b/mozilla/modules/ipc/common/ipcLog.h new file mode 100644 index 00000000000..46f2cc9c772 --- /dev/null +++ b/mozilla/modules/ipc/common/ipcLog.h @@ -0,0 +1,19 @@ +#ifndef ipcLog_h__ +#define ipcLog_h__ + +#include "prtypes.h" + +extern PRBool ipcLogEnabled; +extern void IPC_InitLog(const char *prefix); +extern void IPC_Log(const char *fmt, ...); + +#define IPC_LOG(_args) \ + PR_BEGIN_MACRO \ + if (ipcLogEnabled) \ + IPC_Log _args; \ + PR_END_MACRO + +#define LOG(args) IPC_LOG(args) +#define LOG_ENABLED() ipcLogEnabled + +#endif // !ipcLog_h__ diff --git a/mozilla/modules/ipc/common/ipcMessageQ.h b/mozilla/modules/ipc/common/ipcMessageQ.h index ec2ad7eacd3..fcf2cdd49df 100644 --- a/mozilla/modules/ipc/common/ipcMessageQ.h +++ b/mozilla/modules/ipc/common/ipcMessageQ.h @@ -38,51 +38,9 @@ #ifndef ipcMessageQ_h__ #define ipcMessageQ_h__ -#include "prtypes.h" +#include "ipcMessage.h" +#include "ipcQueue.h" -class ipcMessage; - -//----------------------------------------------------------------------------- -// simple queue of ipcMessage objects -//----------------------------------------------------------------------------- - -class ipcMessageQ -{ -public: - ipcMessageQ() - : mHead(NULL) - , mTail(NULL) - { } - ~ipcMessageQ() { DeleteAll(); } - - // - // appends msg to the end of the queue. caller loses ownership of |msg|. - // - void Append(ipcMessage *msg); - - // - // removes first element w/o deleting it - // - void RemoveFirst() { if (mHead) AdvanceHead(); } - - // - // deletes first element - // - void DeleteFirst(); - - // - // deletes all elements - // - void DeleteAll(); - - ipcMessage *First() { return mHead; } - PRBool IsEmpty() { return mHead == NULL; } - -private: - void AdvanceHead(); - - ipcMessage *mHead; - ipcMessage *mTail; -}; +typedef ipcQueue ipcMessageQ; #endif // !ipcMessageQ_h__ diff --git a/mozilla/modules/ipc/common/ipcMessageUtils.h b/mozilla/modules/ipc/common/ipcMessageUtils.h index f5801d16f8a..99e3e6b80fb 100644 --- a/mozilla/modules/ipc/common/ipcMessageUtils.h +++ b/mozilla/modules/ipc/common/ipcMessageUtils.h @@ -38,6 +38,8 @@ #ifndef ipcMessageUtils_h__ #define ipcMessageUtils_h__ +class ipcMessage; + // // given code like this: // diff --git a/mozilla/modules/ipc/common/ipcMessageQ.cpp b/mozilla/modules/ipc/common/ipcQueue.h similarity index 55% rename from mozilla/modules/ipc/common/ipcMessageQ.cpp rename to mozilla/modules/ipc/common/ipcQueue.h index 7bad8d292ea..64b7ecaddb8 100644 --- a/mozilla/modules/ipc/common/ipcMessageQ.cpp +++ b/mozilla/modules/ipc/common/ipcQueue.h @@ -35,42 +35,82 @@ * * ***** END LICENSE BLOCK ***** */ -#include "ipcMessageQ.h" -#include "ipcMessage.h" +#ifndef ipcQueue_h__ +#define ipcQueue_h__ -void -ipcMessageQ::Append(ipcMessage *msg) +#include "prtypes.h" + +//----------------------------------------------------------------------------- +// simple queue of objects +//----------------------------------------------------------------------------- + +template +class ipcQueue { - msg->mNext = NULL; - if (mTail) { - mTail->mNext = msg; - mTail = msg; +public: + ipcQueue() + : mHead(NULL) + , mTail(NULL) + { } + ~ipcQueue() { DeleteAll(); } + + // + // appends msg to the end of the queue. caller loses ownership of |msg|. + // + void Append(T *obj) + { + obj->mNext = NULL; + if (mTail) { + mTail->mNext = obj; + mTail = obj; + } + else + mTail = mHead = obj; } - else - mTail = mHead = msg; -} -void -ipcMessageQ::AdvanceHead() -{ - mHead = mHead->mNext; - if (!mHead) - mTail = NULL; -} - -void -ipcMessageQ::DeleteFirst() -{ - ipcMessage *first = mHead; - if (first) { - AdvanceHead(); - delete first; + // + // removes first element w/o deleting it + // + void RemoveFirst() + { + if (mHead) + AdvanceHead(); } -} -void -ipcMessageQ::DeleteAll() -{ - while (mHead) - DeleteFirst(); -} + // + // deletes first element + // + void DeleteFirst() + { + T *first = mHead; + if (first) { + AdvanceHead(); + delete first; + } + } + + // + // deletes all elements + // + void DeleteAll() + { + while (mHead) + DeleteFirst(); + } + + T *First() { return mHead; } + PRBool IsEmpty() { return mHead == NULL; } + +private: + void AdvanceHead() + { + mHead = mHead->mNext; + if (!mHead) + mTail = NULL; + } + + T *mHead; + T *mTail; +}; + +#endif // !ipcQueue_h__ diff --git a/mozilla/modules/ipc/common/ipcm.h b/mozilla/modules/ipc/common/ipcm.h index 2f57b2850b7..979c4860be3 100644 --- a/mozilla/modules/ipc/common/ipcm.h +++ b/mozilla/modules/ipc/common/ipcm.h @@ -97,6 +97,8 @@ int IPCM_GetMsgType(const ipcMessage *msg); // IPCM_MSG_TYPE_PING // // this message may be sent from either the client or the daemon. +// if the daemon receives this message, then it will respond by +// sending back a PING to the client. // class ipcmMessagePing : public ipcMessage_DWORD { diff --git a/mozilla/modules/ipc/daemon/ipcClient.cpp b/mozilla/modules/ipc/daemon/ipcClient.cpp index 0ae3ccbfcfd..b06d3ecd52a 100644 --- a/mozilla/modules/ipc/daemon/ipcClient.cpp +++ b/mozilla/modules/ipc/daemon/ipcClient.cpp @@ -36,11 +36,12 @@ * ***** END LICENSE BLOCK ***** */ #include +#include "prio.h" +#include "plstr.h" +#include "ipcLog.h" #include "ipcClient.h" #include "ipcMessage.h" #include "ipcd.h" -#include "prio.h" -#include "plstr.h" int ipcClient::gLastID = 0; @@ -100,7 +101,7 @@ ipcClient::Process(PRFileDesc *fd, int poll_flags) // // expect Finalize method to be called next. // - printf("### client socket appears to have closed\n"); + LOG(("client socket appears to have closed\n")); return 0; } @@ -108,7 +109,7 @@ ipcClient::Process(PRFileDesc *fd, int poll_flags) int ret_flags = PR_POLL_READ; if (poll_flags & PR_POLL_READ) { - printf("### client socket is now readable\n"); + LOG(("client socket is now readable\n")); char buf[1024]; PRInt32 n; @@ -138,7 +139,7 @@ ipcClient::Process(PRFileDesc *fd, int poll_flags) } if (poll_flags & PR_POLL_WRITE) { - printf("### client socket is now writable\n"); + LOG(("client socket is now writable\n")); if (mOutMsgQ.First()) WriteMsgs(fd); @@ -153,7 +154,7 @@ ipcClient::Process(PRFileDesc *fd, int poll_flags) void ipcClient::SetName(const char *name) { - printf("### setting client name to \"%s\"\n", name); + LOG(("setting client name to \"%s\"\n", name)); if (mName) PL_strfree(mName); @@ -179,7 +180,7 @@ ipcClient::WriteMsgs(PRFileDesc *fd) if (nw <= 0) break; - printf("### wrote %d bytes\n", nw); + LOG(("wrote %d bytes\n", nw)); if (nw == bufLen) mOutMsgQ.DeleteFirst(); diff --git a/mozilla/modules/ipc/daemon/ipcCommandModule.cpp b/mozilla/modules/ipc/daemon/ipcCommandModule.cpp index c6adf668b56..8f8eea35a74 100644 --- a/mozilla/modules/ipc/daemon/ipcCommandModule.cpp +++ b/mozilla/modules/ipc/daemon/ipcCommandModule.cpp @@ -35,8 +35,8 @@ * * ***** END LICENSE BLOCK ***** */ -#include #include +#include "ipcLog.h" #include "ipcCommandModule.h" #include "ipcModule.h" #include "ipcClient.h" @@ -58,14 +58,14 @@ public: void handlePing(ipcClient *client, const ipcMessage *rawMsg) { - printf("### got PING\n"); + LOG(("got PING\n")); IPC_SendMsg(client, new ipcmMessagePing()); } void handleClientHello(ipcClient *client, const ipcMessage *rawMsg) { - printf("### got CLIENT_HELLO\n"); + LOG(("got CLIENT_HELLO\n")); ipcMessageCast msg(rawMsg); const char *name = msg->PrimaryName(); @@ -77,7 +77,7 @@ public: void handleForward(ipcClient *client, const ipcMessage *rawMsg) { - printf("### got FORWARD\n"); + LOG(("got FORWARD\n")); ipcMessageCast msg(rawMsg); ipcClient *dest = IPC_GetClientByID(msg->DestClientID()); @@ -128,17 +128,6 @@ public: (this->*handler)(client, rawMsg); } } - -#if 0 - case IPCM_MSG_FWD: - printf("### got fwd\n"); - { - } - break; - default: - printf("### got unknown message\n"); - } -#endif } }; diff --git a/mozilla/modules/ipc/daemon/ipcModuleReg.cpp b/mozilla/modules/ipc/daemon/ipcModuleReg.cpp index b15220be0fa..49e2323d27a 100644 --- a/mozilla/modules/ipc/daemon/ipcModuleReg.cpp +++ b/mozilla/modules/ipc/daemon/ipcModuleReg.cpp @@ -36,7 +36,6 @@ * ***** END LICENSE BLOCK ***** */ #include -#include #include #include "prlink.h" @@ -44,6 +43,7 @@ #include "plstr.h" #include "ipcConfig.h" +#include "ipcLog.h" #include "ipcModuleReg.h" #include "ipcModule.h" #include "ipcCommandModule.h" @@ -65,7 +65,7 @@ static PRStatus AddModule(const nsID &id, ipcModule *module, PRLibrary *lib) { if (ipcModuleCount == IPC_MAX_MODULE_COUNT) { - printf("### too many modules!\n"); + LOG(("too many modules!\n")); return PR_FAILURE; } @@ -80,7 +80,7 @@ AddModule(const nsID &id, ipcModule *module, PRLibrary *lib) static void InitModuleFromLib(const char *modulesDir, const char *fileName) { - printf("### InitModuleFromLib [%s]\n", fileName); + LOG(("InitModuleFromLib [%s]\n", fileName)); int dLen = strlen(modulesDir); int fLen = strlen(fileName); @@ -135,7 +135,7 @@ IPC_InitModuleReg(const char *modulesDir) AddModule(module->ID(), module, NULL); if (modulesDir) { - printf("### loading libraries in %s\n", modulesDir); + LOG(("loading libraries in %s\n", modulesDir)); // // scan directory for IPC modules // diff --git a/mozilla/modules/ipc/daemon/ipcd.cpp b/mozilla/modules/ipc/daemon/ipcd.cpp index 4f9b31ad7e7..36015b473e6 100644 --- a/mozilla/modules/ipc/daemon/ipcd.cpp +++ b/mozilla/modules/ipc/daemon/ipcd.cpp @@ -42,6 +42,7 @@ #ifdef XP_UNIX #include #include +#include #endif #include "prio.h" @@ -51,6 +52,7 @@ #include "plstr.h" #include "ipcConfig.h" +#include "ipcLog.h" #include "ipcMessage.h" #include "ipcClient.h" #include "ipcModuleReg.h" @@ -81,7 +83,7 @@ static int poll_fd_count; static int AddClient(PRFileDesc *fd) { if (poll_fd_count == MAX_CLIENTS + 1) { - printf("### reached maximum client limit\n"); + LOG(("reached maximum client limit\n")); return -1; } @@ -146,7 +148,7 @@ static void Process(PRFileDesc *listen_fd) // rv = PR_Poll(poll_fds, poll_fd_count, PR_SecondsToInterval(60 * 5)); if (rv == -1) { - printf("### PR_Poll failed [%d]\n", PR_GetError()); + LOG(("PR_Poll failed [%d]\n", PR_GetError())); return; } @@ -173,7 +175,7 @@ static void Process(PRFileDesc *listen_fd) // check for new connection // if (poll_fds[0].out_flags & PR_POLL_READ) { - printf("### got new connection\n"); + LOG(("got new connection\n")); PRNetAddr client_addr; memset(&client_addr, 0, sizeof(client_addr)); @@ -181,7 +183,7 @@ static void Process(PRFileDesc *listen_fd) client_fd = PR_Accept(listen_fd, &client_addr, PR_INTERVAL_NO_WAIT); if (client_fd == NULL) { - printf("### PR_Accept failed [%d]\n", PR_GetError()); + LOG(("PR_Accept failed [%d]\n", PR_GetError())); return; } @@ -200,7 +202,7 @@ static void Process(PRFileDesc *listen_fd) // shutdown if no clients // if (poll_fd_count == 1) { - printf("### shutting down\n"); + LOG(("shutting down\n")); break; } } @@ -214,7 +216,7 @@ static void InitModuleReg(const char *exePath) char *p = PL_strrchr(exePath, IPC_PATH_SEP_CHAR); if (p == NULL) { - printf("### unexpected exe path\n"); + LOG(("unexpected exe path\n")); return; } @@ -231,10 +233,6 @@ static void InitModuleReg(const char *exePath) free(buf); } -#ifdef XP_UNIX -#include -#endif - int main(int argc, char **argv) { PRFileDesc *listen_fd; @@ -245,11 +243,15 @@ int main(int argc, char **argv) umask(0077); // ensure strict file permissions #endif +#ifdef DEBUG + IPC_InitLog("###"); +#endif + start: #ifdef IPC_USE_INET listen_fd = PR_OpenTCPSocket(PR_AF_INET); if (!listen_fd) { - printf("### PR_OpenUDPSocket failed [%d]\n", PR_GetError()); + LOG(("PR_OpenUDPSocket failed [%d]\n", PR_GetError())); return -1; } @@ -264,7 +266,7 @@ start: listen_fd = PR_OpenTCPSocket(PR_AF_LOCAL); if (!listen_fd) { - printf("### PR_OpenUDPSocket failed [%d]\n", PR_GetError()); + LOG(("PR_OpenUDPSocket failed [%d]\n", PR_GetError())); return -1; } @@ -273,7 +275,7 @@ start: #endif if (PR_Bind(listen_fd, &addr) != PR_SUCCESS) { - printf("### PR_Bind failed [%d]\n", PR_GetError()); + LOG(("PR_Bind failed [%d]\n", PR_GetError())); // // failure here indicates that another process may be bound // to the socket already. let's try connecting to that socket. @@ -283,26 +285,26 @@ start: // // looks like another process is active. silently exit. // - printf("### looks like another instance of the daemon is active; sleeping...\n"); + LOG(("looks like another instance of the daemon is active; sleeping...\n")); // // sleep here to avoid triggering the shutdown procedure in the // other daemon. 10 seconds should be long enough for the client // to have established a connection. // PR_Sleep(PR_SecondsToInterval(10)); - printf("### exiting\n"); + LOG(("exiting\n")); PR_Close(listen_fd); return 0; } // // OK, the socket is probably stale. // - printf("### socket appears to be stale\n"); + LOG(("socket appears to be stale\n")); #ifdef IPC_USE_INET - printf("### waiting for TIMEWAIT period to expire...\n"); + LOG(("waiting for TIMEWAIT period to expire...\n")); PR_Sleep(PR_SecondsToInterval(60)); #else - printf("### deleting socket at %s\n", socket_path); + LOG(("deleting socket at %s\n", socket_path)); PR_Delete(socket_path); #endif PR_Close(listen_fd); @@ -312,7 +314,7 @@ start: InitModuleReg(argv[0]); if (PR_Listen(listen_fd, 5) != PR_SUCCESS) { - printf("### PR_Listen failed [%d]\n", PR_GetError()); + LOG(("PR_Listen failed [%d]\n", PR_GetError())); return -1; } @@ -323,25 +325,25 @@ start: // // XXX enable this delay for startup testing // - //printf("### sleeping for 5 seconds...\n"); + //LOG(("sleeping for 5 seconds...\n")); //PR_Sleep(PR_SecondsToInterval(5)); #ifndef IPC_USE_INET - printf("### deleting socket at %s\n", socket_path); + LOG(("deleting socket at %s\n", socket_path)); // // we delete the file itself first to avoid a race between shutting // ourselves down and another instance of the daemon starting up. // if (PR_Delete(socket_path) != PR_SUCCESS) { - printf("### PR_Delete failed [%d]\n", PR_GetError()); + LOG(("PR_Delete failed [%d]\n", PR_GetError())); return -1; } #endif - printf("### closing socket\n"); + LOG(("closing socket\n")); if (PR_Close(listen_fd) != PR_SUCCESS) { - printf("### PR_Close failed [%d]\n", PR_GetError()); + LOG(("PR_Close failed [%d]\n", PR_GetError())); return -1; } @@ -359,7 +361,7 @@ int IPC_DispatchMsg(ipcClient *client, const ipcMessage *msg) if (module) module->HandleMsg(client, msg); else - printf("### no registered module; ignoring message\n"); + LOG(("no registered module; ignoring message\n")); return 0; } diff --git a/mozilla/modules/ipc/src/Makefile.in b/mozilla/modules/ipc/src/Makefile.in index c68838323ee..a32808a0ddc 100644 --- a/mozilla/modules/ipc/src/Makefile.in +++ b/mozilla/modules/ipc/src/Makefile.in @@ -51,6 +51,7 @@ MODULE_NAME = ipc REQUIRES = xpcom \ string \ necko \ + pref \ $(NULL) CPPSRCS = \ diff --git a/mozilla/modules/ipc/src/ipcService.cpp b/mozilla/modules/ipc/src/ipcService.cpp index 254690e2d5d..047e0cd588b 100644 --- a/mozilla/modules/ipc/src/ipcService.cpp +++ b/mozilla/modules/ipc/src/ipcService.cpp @@ -37,7 +37,12 @@ #include "plstr.h" +#include "nsIServiceManager.h" +#include "nsIPrefService.h" +#include "nsIPrefBranch.h" + #include "ipcConfig.h" +#include "ipcLog.h" #include "ipcService.h" #include "ipcm.h" @@ -54,8 +59,14 @@ ipcReleaseMessageObserver(nsHashKey *aKey, void *aData, void* aClosure) //----------------------------------------------------------------------------- ipcService::ipcService() + : mTransport(nsnull) + , mClientID(0) { NS_INIT_ISUPPORTS(); + +#ifdef DEBUG + IPC_InitLog(">>>"); +#endif } ipcService::~ipcService() @@ -78,8 +89,26 @@ ipcService::Init() return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(mTransport); + // read preferences + nsCAutoString appName; + nsCOMPtr prefserv(do_GetService(NS_PREFSERVICE_CONTRACTID)); + if (prefserv) { + nsCOMPtr prefbranch; + prefserv->GetBranch(nsnull, getter_AddRefs(prefbranch)); + if (prefbranch) { + nsXPIDLCString val; + prefbranch->GetCharPref("ipc.client-name", getter_Copies(val)); + if (!val.IsEmpty()) + appName = val; + } + } + if (appName.IsEmpty()) + appName = NS_LITERAL_CSTRING("test-app"); + // XXX use directory service to locate socket - rv = mTransport->Init(NS_LITERAL_CSTRING(IPC_DEFAULT_SOCKET_PATH), this); + rv = mTransport->Init(appName, + NS_LITERAL_CSTRING(IPC_DEFAULT_SOCKET_PATH), + this); if (NS_FAILED(rv)) return rv; return NS_OK; @@ -94,7 +123,11 @@ NS_IMPL_ISUPPORTS1(ipcService, ipcIService) NS_IMETHODIMP ipcService::GetClientID(PRUint32 *clientID) { - return NS_ERROR_NOT_IMPLEMENTED; + if (mClientID == 0) + return NS_ERROR_NOT_AVAILABLE; + + *clientID = mClientID; + return NS_OK; } NS_IMETHODIMP @@ -114,7 +147,24 @@ ipcService::QueryClientByName(const nsACString &name, ipcIClientObserver *observer, PRUint32 *token) { - return NS_ERROR_NOT_IMPLEMENTED; + if (!mTransport) + return NS_ERROR_NOT_AVAILABLE; + + ipcMessage *msg; + + msg = new ipcmMessageQueryClientByName(PromiseFlatCString(name).get()); + if (!msg) + return NS_ERROR_OUT_OF_MEMORY; + + nsresult rv; + + rv = mTransport->SendMsg(msg); + if (NS_FAILED(rv)) return rv; + + // + // now queue up the observer and generate a token. + // + return NS_OK; } NS_IMETHODIMP @@ -174,8 +224,7 @@ ipcService::SendMessage(PRUint32 clientID, if (!msg) return NS_ERROR_OUT_OF_MEMORY; - mTransport->SendMsg(msg); - return NS_OK; + return mTransport->SendMsg(msg); } //----------------------------------------------------------------------------- @@ -183,7 +232,19 @@ ipcService::SendMessage(PRUint32 clientID, //----------------------------------------------------------------------------- void -ipcService::OnMsgAvailable(const ipcMessage *msg) +ipcService::OnConnectionEstablished(PRUint32 clientID) +{ + mClientID = clientID; +} + +void +ipcService::OnConnectionLost() +{ + mClientID = 0; +} + +void +ipcService::OnMessageAvailable(const ipcMessage *msg) { nsIDKey key(msg->Target()); diff --git a/mozilla/modules/ipc/src/ipcService.h b/mozilla/modules/ipc/src/ipcService.h index bdabd3296b5..5389a314dd8 100644 --- a/mozilla/modules/ipc/src/ipcService.h +++ b/mozilla/modules/ipc/src/ipcService.h @@ -48,6 +48,25 @@ #include "nsCOMPtr.h" #include "nsHashtable.h" +//---------------------------------------------------------------------------- +// ipcClientQuery +//---------------------------------------------------------------------------- + +/* +class ipcClientQuery +{ +public: + ipcClientQuery() + : mNext(nsnull) + , mReqToken(0) + { } + + ipcClientQuery *mNext; + PRUint32 mReqToken; + nsCOMPtr mObserver; +}; +*/ + //---------------------------------------------------------------------------- // ipcService //---------------------------------------------------------------------------- @@ -66,10 +85,15 @@ public: private: // ipcTransportObserver: - void OnMsgAvailable(const ipcMessage *); + void OnConnectionEstablished(PRUint32 clientID); + void OnConnectionLost(); + void OnMessageAvailable(const ipcMessage *); - nsHashtable mObserverDB; - ipcTransport *mTransport; + nsHashtable mObserverDB; + ipcTransport *mTransport; + PRUint32 mClientID; + + //ipcClientQuery *mQueryQ; }; #endif // !ipcService_h__ diff --git a/mozilla/modules/ipc/src/ipcTransport.cpp b/mozilla/modules/ipc/src/ipcTransport.cpp index 4f364c52af1..5896c7a13cc 100644 --- a/mozilla/modules/ipc/src/ipcTransport.cpp +++ b/mozilla/modules/ipc/src/ipcTransport.cpp @@ -51,11 +51,11 @@ #include "plstr.h" #include "ipcConfig.h" +#include "ipcLog.h" +#include "ipcMessageUtils.h" #include "ipcTransport.h" #include "ipcm.h" -#define LOG(args) printf args - static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID); //----------------------------------------------------------------------------- @@ -69,13 +69,17 @@ ipcTransport::~ipcTransport() } nsresult -ipcTransport::Init(const nsACString &socketPath, ipcTransportObserver *obs) +ipcTransport::Init(const nsACString &appName, + const nsACString &socketPath, + ipcTransportObserver *obs) { - LOG((">>> ipcTransport::Init\n")); + LOG(("ipcTransport::Init\n")); + mAppName = appName; mSocketPath = socketPath; mObserver = obs; + // XXX service should be the observer nsCOMPtr observ(do_GetService("@mozilla.org/observer-service;1")); if (observ) { observ->AddObserver(this, "xpcom-shutdown", PR_FALSE); @@ -88,7 +92,7 @@ ipcTransport::Init(const nsACString &socketPath, ipcTransportObserver *obs) nsresult ipcTransport::Shutdown() { - LOG((">>> ipcTransport::Shutdown\n")); + LOG(("ipcTransport::Shutdown\n")); mHaveConnection = PR_FALSE; @@ -110,10 +114,10 @@ ipcTransport::SendMsg(ipcMessage *msg) { NS_ENSURE_ARG_POINTER(msg); - LOG((">>> ipcTransport::SendMsg [dataLen=%u]\n", msg->DataLen())); + LOG(("ipcTransport::SendMsg [dataLen=%u]\n", msg->DataLen())); if (!mHaveConnection) { - LOG((">>> delaying message until connected\n")); + LOG((" delaying message until connected\n")); mDelayedQ.Append(msg); return NS_OK; } @@ -124,7 +128,7 @@ ipcTransport::SendMsg(ipcMessage *msg) nsresult ipcTransport::SendMsg_Internal(ipcMessage *msg) { - LOG((">>> ipcTransport::SendMsg_Internal [dataLen=%u]\n", msg->DataLen())); + LOG(("ipcTransport::SendMsg_Internal [dataLen=%u]\n", msg->DataLen())); mSendQ.EnqueueMsg(msg); @@ -148,10 +152,10 @@ ipcTransport::Connect() { nsresult rv; - LOG((">>> ipcTransport::Connect\n")); + LOG(("ipcTransport::Connect\n")); if (++mConnectionAttemptCount > 20) { - LOG((">>> giving up after 20 unsuccessful connection attempts\n")); + LOG((" giving up after 20 unsuccessful connection attempts\n")); return NS_ERROR_ABORT; } @@ -164,40 +168,34 @@ ipcTransport::Connect() } void -ipcTransport::OnMsgAvailable(const ipcMessage *rawMsg) +ipcTransport::OnMessageAvailable(const ipcMessage *rawMsg) { - LOG((">>> ipcTransport::OnMsgAvailable [dataLen=%u]\n", rawMsg->DataLen())); + LOG(("ipcTransport::OnMsgAvailable [dataLen=%u]\n", rawMsg->DataLen())); - // - // all IPCM messages stop here. - // - if (rawMsg->Target().Equals(IPCM_TARGET)) { - // - // check for startup PING - // - if (!mHaveConnection) { + if (!mHaveConnection) { + if (rawMsg->Target().Equals(IPCM_TARGET)) { if (IPCM_GetMsgType(rawMsg) == IPCM_MSG_TYPE_CLIENT_ID) { - LOG((">>> connection established!\n")); + LOG((" connection established!\n")); mHaveConnection = PR_TRUE; - /* XXX inform the service that we now know our ID + + // remember our client ID ipcMessageCast msg(rawMsg); - msg->ClientID(); - */ - // - // move messages off the delayed queue - // + if (mObserver) + mObserver->OnConnectionEstablished(msg->ClientID()); + + // move messages off the delayed message queue while (!mDelayedQ.IsEmpty()) { ipcMessage *msg = mDelayedQ.First(); mDelayedQ.RemoveFirst(); SendMsg_Internal(msg); } + return; } - else - LOG((">>> received bogus response to our ping!\n")); } + LOG((" received unexpected first message!\n")); } else if (mObserver) - mObserver->OnMsgAvailable(rawMsg); + mObserver->OnMessageAvailable(rawMsg); } void @@ -210,7 +208,7 @@ ipcTransport::OnStartRequest(nsIRequest *req) // // send CLIENT_HELLO; expect CLIENT_ID in response. // - SendMsg_Internal(new ipcmMessageClientHello("test-app")); // XXX need real client name + SendMsg_Internal(new ipcmMessageClientHello(mAppName.get())); mSentHello = PR_TRUE; } } @@ -218,7 +216,13 @@ ipcTransport::OnStartRequest(nsIRequest *req) void ipcTransport::OnStopRequest(nsIRequest *req, nsresult status) { - LOG((">>> ipcTransport::OnStopRequest [status=%x]\n", status)); + LOG(("ipcTransport::OnStopRequest [status=%x]\n", status)); + + if (mHaveConnection) { + mHaveConnection = PR_FALSE; + if (mObserver) + mObserver->OnConnectionLost(); + } if (status == NS_BINDING_ABORTED) return; @@ -230,7 +234,7 @@ ipcTransport::OnStopRequest(nsIRequest *req, nsresult status) // rv = SpawnDaemon(); if (NS_FAILED(rv)) { - LOG((">>> failed to spawn daemon [rv=%x]\n", rv)); + LOG((" failed to spawn daemon [rv=%x]\n", rv)); return; } @@ -239,18 +243,18 @@ ipcTransport::OnStopRequest(nsIRequest *req, nsresult status) // mTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv); if (NS_FAILED(rv)) { - LOG((">>> failed to create timer [rv=%x]\n", rv)); + LOG((" failed to create timer [rv=%x]\n", rv)); return; } // use a simple exponential growth algorithm n*2^(n-1) PRUint32 ms = 1000 * (1 << (mConnectionAttemptCount - 1)); - LOG((">>> waiting %u milliseconds\n", ms)); + LOG((" waiting %u milliseconds\n", ms)); rv = mTimer->Init(this, ms, nsITimer::TYPE_ONE_SHOT); if (NS_FAILED(rv)) { - LOG((">>> failed to initialize timer [rv=%x]\n", rv)); + LOG((" failed to initialize timer [rv=%x]\n", rv)); return; } } @@ -297,7 +301,7 @@ ipcTransport::CreateTransport() nsresult ipcTransport::SpawnDaemon() { - LOG((">>> ipcTransport::SpawnDaemon\n")); + LOG(("ipcTransport::SpawnDaemon\n")); nsresult rv; nsCOMPtr file; @@ -323,7 +327,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS0(ipcTransport) NS_IMETHODIMP ipcTransport::Observe(nsISupports *subject, const char *topic, const PRUnichar *data) { - LOG((">>> ipcTransport::Observe [topic=%s]\n", topic)); + LOG(("ipcTransport::Observe [topic=%s]\n", topic)); if (strcmp(topic, "timer-callback") == 0) { // @@ -363,7 +367,7 @@ NS_IMETHODIMP ipcSendQueue::OnStartRequest(nsIRequest *request, nsISupports *context) { - LOG((">>> ipcSendQueue::OnStartRequest\n")); + LOG(("ipcSendQueue::OnStartRequest\n")); if (mTransport) mTransport->OnStartRequest(request); @@ -376,7 +380,7 @@ ipcSendQueue::OnStopRequest(nsIRequest *request, nsISupports *context, nsresult status) { - LOG((">>> ipcSendQueue::OnStopRequest [status=%x]\n", status)); + LOG(("ipcSendQueue::OnStopRequest [status=%x]\n", status)); if (mTransport) mTransport->OnStopRequest(request, status); @@ -418,7 +422,7 @@ ipcSendQueue::OnDataWritable(nsIRequest *request, ipcWriteState state; PRBool wroteSomething = PR_FALSE; - LOG((">>> ipcSendQueue::OnDataWritable\n")); + LOG(("ipcSendQueue::OnDataWritable\n")); while (!mQueue.IsEmpty()) { state.msg = mQueue.First(); @@ -429,7 +433,7 @@ ipcSendQueue::OnDataWritable(nsIRequest *request, break; if (state.complete) { - LOG((">>> wrote message %u bytes\n", mQueue.First()->MsgLen())); + LOG((" wrote message %u bytes\n", mQueue.First()->MsgLen())); mQueue.DeleteFirst(); } @@ -439,7 +443,7 @@ ipcSendQueue::OnDataWritable(nsIRequest *request, if (wroteSomething) return NS_OK; - LOG((">>> suspending write request\n")); + LOG((" suspending write request\n")); mTransport->SetWriteSuspended(PR_TRUE); return NS_BASE_STREAM_WOULD_BLOCK; @@ -467,7 +471,7 @@ NS_IMETHODIMP ipcReceiver::OnStartRequest(nsIRequest *request, nsISupports *context) { - LOG((">>> ipcReceiver::OnStartRequest\n")); + LOG(("ipcReceiver::OnStartRequest\n")); if (mTransport) mTransport->OnStartRequest(request); @@ -480,7 +484,7 @@ ipcReceiver::OnStopRequest(nsIRequest *request, nsISupports *context, nsresult status) { - LOG((">>> ipcReceiver::OnStopRequest [status=%x]\n", status)); + LOG(("ipcReceiver::OnStopRequest [status=%x]\n", status)); if (mTransport) mTransport->OnStopRequest(request, status); @@ -506,7 +510,7 @@ ipcReceiver::OnDataAvailable(nsIRequest *request, PRUint32 offset, PRUint32 count) { - LOG((">>> ipcReceiver::OnDataAvailable [count=%u]\n", count)); + LOG(("ipcReceiver::OnDataAvailable [count=%u]\n", count)); PRUint32 countRead; return stream->ReadSegments(ipcReadMessage, this, count, &countRead); @@ -523,7 +527,7 @@ ipcReceiver::ReadSegment(const char *ptr, PRUint32 count, PRUint32 *countRead) mMsg.ReadFrom(ptr, count, &nread, &complete); if (complete) { - mTransport->OnMsgAvailable(&mMsg); + mTransport->OnMessageAvailable(&mMsg); mMsg.Reset(); } diff --git a/mozilla/modules/ipc/src/ipcTransport.h b/mozilla/modules/ipc/src/ipcTransport.h index f9ca0f8b086..83dac36901e 100644 --- a/mozilla/modules/ipc/src/ipcTransport.h +++ b/mozilla/modules/ipc/src/ipcTransport.h @@ -59,7 +59,9 @@ class ipcTransport; class ipcTransportObserver { public: - virtual void OnMsgAvailable(const ipcMessage *) = 0; + virtual void OnConnectionEstablished(PRUint32 clientID) = 0; + virtual void OnConnectionLost() = 0; + virtual void OnMessageAvailable(const ipcMessage *) = 0; }; //---------------------------------------------------------------------------- @@ -132,15 +134,19 @@ public: { } virtual ~ipcTransport(); - nsresult Init(const nsACString &socketPath, ipcTransportObserver *); + nsresult Init(const nsACString &appName, + const nsACString &socketPath, + ipcTransportObserver *observer); nsresult Shutdown(); // takes ownership of |msg| nsresult SendMsg(ipcMessage *msg); + PRBool HaveConnection() const { return mHaveConnection; } + public: // internal to implementation - void OnMsgAvailable(const ipcMessage *); + void OnMessageAvailable(const ipcMessage *); void SetWriteSuspended(PRBool val) { mWriteSuspended = val; } void OnStartRequest(nsIRequest *req); void OnStopRequest(nsIRequest *req, nsresult status); @@ -166,6 +172,7 @@ private: nsCOMPtr mReadRequest; nsCOMPtr mWriteRequest; nsCOMPtr mTimer; + nsCString mAppName; nsCString mSocketPath; PRFileDesc *mFD; PRPackedBool mWriteSuspended; diff --git a/mozilla/modules/ipc/test/Makefile.in b/mozilla/modules/ipc/test/Makefile.in index 0710315ca4f..b8ff626a4db 100644 --- a/mozilla/modules/ipc/test/Makefile.in +++ b/mozilla/modules/ipc/test/Makefile.in @@ -30,6 +30,7 @@ MODULE = test_ipc REQUIRES = xpcom \ string \ ipc \ + pref \ $(NULL) CPPSRCS = \ diff --git a/mozilla/modules/ipc/test/TestIPC.cpp b/mozilla/modules/ipc/test/TestIPC.cpp index 1ad8c190ca7..f3a7b35f160 100644 --- a/mozilla/modules/ipc/test/TestIPC.cpp +++ b/mozilla/modules/ipc/test/TestIPC.cpp @@ -36,6 +36,8 @@ * ***** END LICENSE BLOCK ***** */ #include "ipcIService.h" +#include "nsIPrefService.h" +#include "nsIPrefBranch.h" #include "nsIEventQueueService.h" #include "nsIServiceManager.h" #include "nsIComponentRegistrar.h" @@ -60,7 +62,7 @@ static const nsID TestTargetID = static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static nsIEventQueue* gEventQ = nsnull; static PRBool gKeepRunning = PR_TRUE; -static PRInt32 gMsgCount = 0; +//static PRInt32 gMsgCount = 0; class myIpcMessageObserver : public ipcIMessageObserver { @@ -81,8 +83,8 @@ myIpcMessageObserver::OnMessageAvailable(const nsID &target, const char *data, P { printf("*** got message: [%s]\n", data); - if (--gMsgCount == 0) - gKeepRunning = PR_FALSE; +// if (--gMsgCount == 0) +// gKeepRunning = PR_FALSE; return NS_OK; } @@ -92,7 +94,7 @@ void SendMsg(ipcIService *ipc, const nsID &target, const char *data, PRUint32 da printf("*** sending message: [dataLen=%u]\n", dataLen); ipc->SendMessage(0, target, data, dataLen); - gMsgCount++; +// gMsgCount++; } int main(int argc, char **argv) @@ -118,6 +120,17 @@ int main(int argc, char **argv) rv = eqs->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); RETURN_IF_FAILED(rv, "GetThreadEventQueue"); + if (argc > 1) { + printf("*** using client name [%s]\n", argv[1]); + nsCOMPtr prefserv(do_GetService(NS_PREFSERVICE_CONTRACTID)); + if (prefserv) { + nsCOMPtr prefbranch; + prefserv->GetBranch(nsnull, getter_AddRefs(prefbranch)); + if (prefbranch) + prefbranch->SetCharPref("ipc.client-name", argv[1]); + } + } + nsCOMPtr ipcServ(do_GetService("@mozilla.org/ipc/service;1", &rv)); RETURN_IF_FAILED(rv, "do_GetService(ipcServ)");