ipc/glue imported verbatim from http://hg.mozilla.org/users/bturner_mozilla.com/libchromiumipc/
ipc/glue imported verbatim from http://hg.mozilla.org/users/bturner_mozilla.com/libchromiumipc/
--- a/ipc/Makefile.in
+++ b/ipc/Makefile.in
@@ -36,11 +36,11 @@
DEPTH = ..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
-DIRS += chromium
+DIRS += chromium glue
include $(topsrcdir)/config/rules.mk
--- a/ipc/chromium/Makefile.in
+++ b/ipc/chromium/Makefile.in
@@ -286,10 +286,8 @@ CSRCS += \
$(NULL)
endif # }
endif # }
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
-
-CXXFLAGS += $(MOZ_RTTI_FLAGS_ON)
--- a/ipc/chromium/chromium-config.mk
+++ b/ipc/chromium/chromium-config.mk
@@ -39,25 +39,26 @@ ifndef INCLUDED_CONFIG_MK
endif
ifdef CHROMIUM_CONFIG_INCLUDED
$(error Must not include chromium-config.mk twice.)
endif
CHROMIUM_CONFIG_INCLUDED = 1
-EXTRA_DEPS += $(topsrcdir)/ipc/chromium/chromium-defs.mk
+EXTRA_DEPS += $(topsrcdir)/ipc/chromium/chromium-config.mk
DEFINES += \
-DEXCLUDE_SKIA_DEPENDENCIES \
-DCHROMIUM_MOZILLA_BUILD \
$(NULL)
LOCAL_INCLUDES += \
-I$(topsrcdir)/ipc/chromium/src \
+ -I$(topsrcdir)/ipc/glue \
$(NULL)
ifeq ($(OS_ARCH),Darwin) # {
OS_MACOSX = 1
OS_POSIX = 1
DEFINES += \
@@ -103,8 +104,12 @@ DEFINES += \
OS_CXXFLAGS := $(filter-out -pedantic,$(OS_CXXFLAGS))
# TODO support !GTK
OS_CXXFLAGS += $(MOZ_GTK2_CFLAGS)
OS_CFLAGS += $(MOZ_GTK2_CFLAGS)
endif # }
endif # }
+
+ifdef OS_POSIX
+CXXFLAGS += $(MOZ_RTTI_FLAGS_ON)
+endif
new file mode 100644
--- /dev/null
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -0,0 +1,103 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPC.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "GeckoChildProcessHost.h"
+
+#include "base/command_line.h"
+#include "base/path_service.h"
+#include "chrome/common/chrome_switches.h"
+
+using mozilla::ipc::GeckoChildProcessHost;
+
+GeckoChildProcessHost::GeckoChildProcessHost(ProcessType type)
+: ChildProcessHost(type)
+{
+}
+
+bool
+GeckoChildProcessHost::Init()
+{
+ if (!CreateChannel()) {
+ return false;
+ }
+
+ FilePath exePath =
+ FilePath::FromWStringHack(CommandLine::ForCurrentProcess()->program());
+ exePath = exePath.DirName();
+
+#if defined(OS_WIN)
+ exePath = exePath.AppendASCII("mozilla-runtime.exe");
+ // no fd mapping necessary
+#elif defined(OS_POSIX)
+ exePath = exePath.AppendASCII("mozilla-runtime");
+
+ int srcChannelFd, dstChannelFd;
+ channel().GetClientFileDescriptorMapping(&srcChannelFd, &dstChannelFd);
+ mFileMap.push_back(std::pair<int,int>(srcChannelFd, dstChannelFd));
+#else
+#error Bad!
+#endif
+
+ CommandLine cmdLine(exePath.ToWStringHack());
+ cmdLine.AppendSwitchWithValue(switches::kProcessChannelID, channel_id());
+
+ base::ProcessHandle process;
+#if defined(OS_WIN)
+ base::LaunchApp(cmdLine, false, false, &process);
+#elif defined(OS_POSIX)
+ base::LaunchApp(cmdLine.argv(), mFileMap, false, &process);
+#else
+#error Bad!
+#endif
+
+ if (!process) {
+ return false;
+ }
+ SetHandle(process);
+
+ return true;
+}
+
+void
+GeckoChildProcessHost::OnMessageReceived(const IPC::Message& aMsg)
+{
+}
+
+void
+GeckoChildProcessHost::OnChannelError()
+{
+ // XXXbent Notify that the child process is gone?
+}
new file mode 100644
--- /dev/null
+++ b/ipc/glue/GeckoChildProcessHost.h
@@ -0,0 +1,76 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPC.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __IPC_GLUE_GECKOCHILDPROCESSHOST_H__
+#define __IPC_GLUE_GECKOCHILDPROCESSHOST_H__
+
+#include "base/file_path.h"
+#include "base/process_util.h"
+#include "base/scoped_ptr.h"
+#include "base/waitable_event.h"
+#include "chrome/common/child_process_host.h"
+
+namespace mozilla {
+namespace ipc {
+
+class GeckoChildProcessHost : public ChildProcessHost
+{
+public:
+ GeckoChildProcessHost(ProcessType type=RENDER_PROCESS);
+
+ bool Init();
+
+ virtual void OnMessageReceived(const IPC::Message& aMsg);
+ virtual void OnChannelError();
+
+ virtual bool CanShutdown() { return true; }
+
+protected:
+
+ FilePath mProcessPath;
+
+#if defined(OS_POSIX)
+ base::file_handle_mapping_vector mFileMap;
+#endif
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(GeckoChildProcessHost);
+};
+
+} /* namespace ipc */
+} /* namespace mozilla */
+
+#endif /* __IPC_GLUE_GECKOCHILDPROCESSHOST_H__ */
new file mode 100644
--- /dev/null
+++ b/ipc/glue/GeckoThread.cpp
@@ -0,0 +1,162 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mozilla/ipc/GeckoThread.h"
+
+#include "chrome/common/notification_service.h"
+
+#include "nsXPCOM.h"
+
+#if defined(OS_WIN)
+#include <objbase.h>
+#endif
+
+using mozilla::ipc::GeckoThread;
+using mozilla::ipc::BrowserProcessSubThread;
+
+void
+GeckoThread::OnControlMessageReceived(const IPC::Message& aMessage) {
+ /*
+ IPC_BEGIN_MESSAGE_MAP(GeckoThread, aMessage)
+ IPC_END_MESSAGE_MAP()
+ */
+}
+
+void
+GeckoThread::Init()
+{
+ ChildThread::Init();
+
+ // Certain plugins, such as flash, steal the unhandled exception filter
+ // thus we never get crash reports when they fault. This call fixes it.
+ message_loop()->set_exception_restoration(true);
+
+ NS_LogInit();
+ mXREEmbed.Start();
+}
+
+void
+GeckoThread::CleanUp()
+{
+ mXREEmbed.Stop();
+ NS_LogTerm();
+
+ // Maybe kill process?
+
+ // Call this last according to chrome source comments.
+ ChildThread::CleanUp();
+}
+
+//
+// BrowserProcessSubThread
+//
+
+// Friendly names for the well-known threads.
+static const char* kBrowserThreadNames[BrowserProcessSubThread::ID_COUNT] = {
+ "Gecko_IOThread", // IO
+// "Chrome_FileThread", // FILE
+// "Chrome_DBThread", // DB
+// "Chrome_HistoryThread", // HISTORY
+#if defined(OS_LINUX)
+ "Gecko_Background_X11Thread", // BACKGROUND_X11
+#endif
+};
+
+Lock BrowserProcessSubThread::sLock;
+BrowserProcessSubThread* BrowserProcessSubThread::sBrowserThreads[ID_COUNT] = {
+ NULL, // IO
+// NULL, // FILE
+// NULL, // DB
+// NULL, // HISTORY
+#if defined(OS_LINUX)
+ NULL, // BACKGROUND_X11
+#endif
+};
+
+BrowserProcessSubThread::BrowserProcessSubThread(ID aId) :
+ base::Thread(kBrowserThreadNames[aId]),
+ mIdentifier(aId),
+ mNotificationService(NULL)
+{
+ AutoLock lock(sLock);
+ DCHECK(aId >= 0 && aId < ID_COUNT);
+ DCHECK(sBrowserThreads[aId] == NULL);
+ sBrowserThreads[aId] = this;
+}
+
+BrowserProcessSubThread::~BrowserProcessSubThread()
+{
+ Stop();
+ {AutoLock lock(sLock);
+ sBrowserThreads[mIdentifier] = NULL;
+ }
+
+}
+
+void
+BrowserProcessSubThread::Init()
+{
+#if defined(OS_WIN)
+ // Initializes the COM library on the current thread.
+ CoInitialize(NULL);
+#endif
+ mNotificationService = new NotificationService();
+}
+
+void
+BrowserProcessSubThread::CleanUp()
+{
+ delete mNotificationService;
+ mNotificationService = NULL;
+
+#if defined(OS_WIN)
+ // Closes the COM library on the current thread. CoInitialize must
+ // be balanced by a corresponding call to CoUninitialize.
+ CoUninitialize();
+#endif
+}
+
+// static
+MessageLoop*
+BrowserProcessSubThread::GetMessageLoop(ID aId) {
+ AutoLock lock(sLock);
+ DCHECK(aId >= 0 && aId < ID_COUNT);
+
+ if (sBrowserThreads[aId])
+ return sBrowserThreads[aId]->message_loop();
+
+ return NULL;
+}
new file mode 100644
--- /dev/null
+++ b/ipc/glue/GeckoThread.h
@@ -0,0 +1,127 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __IPC_GLUE_GECKOTHREAD_H__
+#define __IPC_GLUE_GECKOTHREAD_H__
+
+#include "base/thread.h"
+#include "base/lock.h"
+
+#include "chrome/common/child_thread.h"
+
+#include "mozilla/ipc/ScopedXREEmbed.h"
+
+class NotificationService;
+
+namespace mozilla {
+namespace ipc {
+
+class GeckoThread : public ChildThread
+{
+public:
+ GeckoThread()
+ : ChildThread(base::Thread::Options(MessageLoop::TYPE_MOZILLA_CHILD, 0))
+ { }
+
+protected:
+ virtual void OnControlMessageReceived(const IPC::Message& aMessage);
+
+ // Thread implementation:
+ virtual void Init();
+ virtual void CleanUp();
+
+ ScopedXREEmbed mXREEmbed;
+
+ DISALLOW_EVIL_CONSTRUCTORS(GeckoThread);
+};
+
+// Copied from browser_process_impl.cc, modified slightly.
+class BrowserProcessSubThread : public base::Thread
+{
+public:
+ // An enumeration of the well-known threads.
+ enum ID {
+ IO,
+ //FILE,
+ //DB,
+ //HISTORY,
+#if defined(OS_LINUX)
+ // This thread has a second connection to the X server and is used
+ // to process UI requests when routing the request to the UI
+ // thread would risk deadlock.
+ BACKGROUND_X11,
+#endif
+
+ // This identifier does not represent a thread. Instead it counts
+ // the number of well-known threads. Insert new well-known
+ // threads before this identifier.
+ ID_COUNT
+ };
+
+ explicit BrowserProcessSubThread(ID aId);
+ ~BrowserProcessSubThread();
+
+ static MessageLoop* GetMessageLoop(ID identifier);
+
+protected:
+ virtual void Init();
+ virtual void CleanUp();
+
+private:
+ // The identifier of this thread. Only one thread can exist with a given
+ // identifier at a given time.
+ ID mIdentifier;
+
+ NotificationService* mNotificationService;
+
+ // This lock protects |browser_threads_|. Do not read or modify that array
+ // without holding this lock. Do not block while holding this lock.
+
+ // FIXME/cjones: XPCOM doesn't like static vars, so can't use
+ // mozilla::Mutex
+ static Lock sLock;
+
+ // An array of the ChromeThread objects. This array is protected by |lock_|.
+ // The threads are not owned by this array. Typically, the threads are owned
+ // on the UI thread by the g_browser_process object. ChromeThreads remove
+ // themselves from this array upon destruction.
+ static BrowserProcessSubThread* sBrowserThreads[ID_COUNT];
+};
+
+} /* namespace ipc */
+} /* namespace mozilla */
+
+#endif /* __IPC_GLUE_GECKOTHREAD_H__ */
new file mode 100644
--- /dev/null
+++ b/ipc/glue/IPCMessageUtils.h
@@ -0,0 +1,246 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPC.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __IPC_GLUE_IPCMESSAGEUTILS_H__
+#define __IPC_GLUE_IPCMESSAGEUTILS_H__
+
+#include "chrome/common/ipc_message_utils.h"
+
+#include "prtypes.h"
+#include "nsStringGlue.h"
+#include "nsTArray.h"
+
+// Used by chrome code, we override this here and #ifdef theirs out. See the
+// comments in chrome/common/ipc_message_utils.h for info about this enum.
+enum IPCMessageStart {
+ NPAPI_ParentToChildMsgStart = 0,
+ NPAPI_ChildToParentMsgStart,
+ NPP_ParentToChildMsgStart,
+ NPP_ChildToParentMsgStart,
+ NPObject_ParentToChildMsgStart,
+ NPObject_ChildToParentMsgStart,
+
+ IFrameEmbedding_ParentToChildMsgStart,
+ IFrameEmbedding_ChildToParentMsgStart,
+
+ LastMsgIndex
+};
+
+COMPILE_ASSERT(LastMsgIndex <= 16, need_to_update_IPC_MESSAGE_MACRO);
+
+namespace IPC {
+
+
+// FIXME/cjones: PRInt16 traits had a stack corruption bug that took
+// a long time to find. putting these on ice until we need them
+#if 0
+
+template <>
+struct ParamTraits<PRUint8>
+{
+ typedef PRUint8 paramType;
+
+ static void Write(Message* aMsg, const paramType& aParam)
+ {
+ aMsg->WriteBytes(&aParam, sizeof(aParam));
+ }
+
+ static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+ {
+ return aMsg->ReadBytes(aIter, reinterpret_cast<const char**>(aResult),
+ sizeof(*aResult));
+ }
+
+ static void Log(const paramType& aParam, std::wstring* aLog)
+ {
+ aLog->append(StringPrintf(L"%u", aParam));
+ }
+};
+
+template <>
+struct ParamTraits<PRInt8>
+{
+ typedef PRInt8 paramType;
+
+ static void Write(Message* aMsg, const paramType& aParam)
+ {
+ aMsg->WriteBytes(&aParam, sizeof(aParam));
+ }
+
+ static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+ {
+ return aMsg->ReadBytes(aIter, reinterpret_cast<const char**>(aResult),
+ sizeof(*aResult));
+ }
+
+ static void Log(const paramType& aParam, std::wstring* aLog)
+ {
+ aLog->append(StringPrintf(L"%d", aParam));
+ }
+};
+
+template <>
+struct ParamTraits<nsACString>
+{
+ typedef nsACString paramType;
+
+ static void Write(Message* aMsg, const paramType& aParam)
+ {
+ PRUint32 length = aParam.Length();
+ WriteParam(aMsg, length);
+ aMsg->WriteBytes(aParam.BeginReading(), length);
+ }
+
+ static bool Read(const Message* aMsg, void** aIter, paramType& aResult)
+ {
+ PRUint32 length;
+ if (ReadParam(aMsg, aIter, &length)) {
+ const char* buf;
+ if (aMsg->ReadBytes(aIter, &buf, length)) {
+ aResult.Assign(buf, length);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static void Log(const paramType& aParam, std::wstring* aLog)
+ {
+ aLog->append(UTF8ToWide(aParam.BeginReading()));
+ }
+};
+
+template <>
+struct ParamTraits<nsAString>
+{
+ typedef nsAString paramType;
+
+ static void Write(Message* aMsg, const paramType& aParam)
+ {
+ PRUint32 length = aParam.Length();
+ WriteParam(aMsg, length);
+ aMsg->WriteBytes(aParam.BeginReading(), length * sizeof(PRUnichar));
+ }
+
+ static bool Read(const Message* aMsg, void** aIter, paramType& aResult)
+ {
+ PRUint32 length;
+ if (ReadParam(aMsg, aIter, &length)) {
+ const PRUnichar* buf;
+ if (aMsg->ReadBytes(aIter, reinterpret_cast<const char**>(&buf),
+ length * sizeof(PRUnichar))) {
+ aResult.Assign(buf, length);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static void Log(const paramType& aParam, std::wstring* aLog)
+ {
+#ifdef WCHAR_T_IS_UTF16
+ aLog->append(reinterpret_cast<const wchar_t*>(aParam.BeginReading()));
+#else
+ PRUint32 length = aParam.Length();
+ for (PRUint32 index = 0; index < length; index++) {
+ aLog->push_back(std::wstring::value_type(aParam[index]));
+ }
+#endif
+ }
+};
+
+template <typename E>
+struct ParamTraits<nsTArray<E> >
+{
+ typedef nsTArray<E> paramType;
+
+ static void Write(Message* aMsg, const paramType& aParam)
+ {
+ PRUint32 length = aParam.Length();
+ WriteParam(aMsg, length);
+ for (PRUint32 index = 0; index < length; index++) {
+ WriteParam(aMsg, aParam[index]);
+ }
+ }
+
+ static bool Read(const Message* aMsg, void** aIter, paramType& aResult)
+ {
+ PRUint32 length;
+ if (!ReadParam(aMsg, aIter, &length)) {
+ return false;
+ }
+
+ // Check to make sure the message is valid before requesting a huge chunk
+ // of memory.
+ if (aMsg->IteratorHasRoomFor(*aIter, length * sizeof(E)) &&
+ aResult.SetCapacity(length)) {
+ for (PRUint32 index = 0; index < length; index++) {
+ if (!ReadParam(aMsg, aIter, &aResult[index])) {
+ return false;
+ }
+ }
+ }
+ else {
+ // Push elements individually.
+ aResult.Clear();
+ E element;
+ for (PRUint32 index = 0; index < length; index++) {
+ if (!ReadParam(aMsg, aIter, &element) ||
+ !aResult.AppendElement(element)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ static void Log(const paramType& aParam, std::wstring* aLog)
+ {
+ for (PRUint32 index = 0; index < aParam.Length(); index++) {
+ if (index) {
+ aLog->append(L" ");
+ }
+ LogParam(aParam[index], aLog);
+ }
+ }
+};
+
+#endif
+
+} /* namespace IPC */
+
+#endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */
new file mode 100644
--- /dev/null
+++ b/ipc/glue/Makefile.in
@@ -0,0 +1,87 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla IPC.
+#
+# The Initial Developer of the Original Code is
+# Ben Turner <bent.mozilla@gmail.com>.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = ipc
+LIBRARY_NAME = mozipc_s
+FORCE_STATIC_LIB = 1
+LIBXUL_LIBRARY = 1
+
+EXPORTS_NAMESPACES = IPC mozilla/ipc
+
+EXPORTS_IPC = \
+ IPCMessageUtils.h \
+ $(NULL)
+
+# FIXME/cjones: "ChromeThread" is a misnomer
+EXPORTS_mozilla/ipc = \
+ GeckoChildProcessHost.h \
+ GeckoThread.h \
+ MessageTypes.h \
+ RPCChannel.h \
+ ScopedXREEmbed.h \
+ $(NULL)
+
+ENABLE_CXX_EXCEPTIONS = 1
+DEFINES += -DNO_NSPR_10_SUPPORT=1
+
+REQUIRES += \
+ string \
+ widget \
+ xpcom \
+ xulapp \
+ $(NULL)
+
+CPPSRCS += \
+ GeckoChildProcessHost.cpp \
+ GeckoThread.cpp \
+ MessagePump.cpp \
+ RPCChannel.cpp \
+ ScopedXREEmbed.cpp \
+ StringUtil.cpp \
+ $(NULL)
+
+# ChromeThread.cpp \
+
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/ipc/glue/MessagePump.cpp
@@ -0,0 +1,235 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPC.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "MessagePump.h"
+
+#include "nsIAppShell.h"
+#include "nsIThread.h"
+#include "nsIThreadInternal.h"
+
+#include "nsCOMPtr.h"
+#include "nsServiceManagerUtils.h"
+#include "nsStringGlue.h"
+#include "nsThreadUtils.h"
+#include "nsWidgetsCID.h"
+#include "prthread.h"
+
+#include "base/logging.h"
+#include "base/scoped_nsautorelease_pool.h"
+
+using mozilla::ipc::MessagePump;
+using mozilla::ipc::MessagePumpForChildProcess;
+
+static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
+
+namespace mozilla {
+namespace ipc {
+
+class UIThreadObserver : public nsIThreadObserver
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSITHREADOBSERVER
+
+ UIThreadObserver(MessagePump& aPump,
+ nsIThreadObserver* aRealObserver)
+ : mPump(aPump),
+ mRealObserver(aRealObserver),
+ mPRThread(PR_GetCurrentThread())
+ {
+ NS_ASSERTION(aRealObserver, "This should never be null!");
+ }
+
+private:
+ MessagePump& mPump;
+ nsIThreadObserver* mRealObserver;
+ PRThread* mPRThread;
+};
+
+} /* namespace ipc */
+} /* namespace mozilla */
+
+using mozilla::ipc::UIThreadObserver;
+
+NS_IMETHODIMP_(nsrefcnt)
+UIThreadObserver::AddRef()
+{
+ return 2;
+}
+
+NS_IMETHODIMP_(nsrefcnt)
+UIThreadObserver::Release()
+{
+ return 1;
+}
+
+NS_IMPL_QUERY_INTERFACE1(UIThreadObserver, nsIThreadObserver)
+
+NS_IMETHODIMP
+UIThreadObserver::OnDispatchedEvent(nsIThreadInternal* aThread)
+{
+ // XXXbent See if we can figure out some faster way of doing this. On posix
+ // the Signal() call grabs a lock and on windows it calls SetEvent. Seems
+ // like a good idea to avoid calling Signal if we're on the main thead.
+ if (PR_GetCurrentThread() != mPRThread) {
+ mPump.event_.Signal();
+ }
+ return mRealObserver->OnDispatchedEvent(aThread);
+}
+
+NS_IMETHODIMP
+UIThreadObserver::OnProcessNextEvent(nsIThreadInternal* aThread,
+ PRBool aMayWait,
+ PRUint32 aRecursionDepth)
+{
+ return mRealObserver->OnProcessNextEvent(aThread, aMayWait, aRecursionDepth);
+}
+
+NS_IMETHODIMP
+UIThreadObserver::AfterProcessNextEvent(nsIThreadInternal* aThread,
+ PRUint32 aRecursionDepth)
+{
+ return mRealObserver->AfterProcessNextEvent(aThread, aRecursionDepth);
+}
+
+void
+MessagePump::Run(MessagePump::Delegate* aDelegate)
+{
+ NS_ASSERTION(keep_running_, "Quit must have been called outside of Run!");
+
+ nsCOMPtr<nsIThread> thread(do_GetCurrentThread());
+ NS_ASSERTION(thread, "This should never be null!");
+
+ nsCOMPtr<nsIThreadInternal> threadInternal(do_QueryInterface(thread));
+ NS_ASSERTION(threadInternal, "QI failed?!");
+
+ nsCOMPtr<nsIThreadObserver> realObserver;
+ threadInternal->GetObserver(getter_AddRefs(realObserver));
+ NS_ASSERTION(realObserver, "This should never be null!");
+
+ UIThreadObserver observer(*this, realObserver);
+ threadInternal->SetObserver(&observer);
+
+#ifdef DEBUG
+ {
+ nsCOMPtr<nsIAppShell> appShell(do_QueryInterface(realObserver));
+ NS_ASSERTION(appShell, "Should be the app shell!");
+ }
+#endif
+
+
+ for (;;) {
+ // XXXbent This looks fishy... Maybe have one that calls Recycle each time
+ // through the loop? Copied straight from message_pump_default.
+ base::ScopedNSAutoreleasePool autorelease_pool;
+
+ bool did_work = NS_ProcessNextEvent(thread, PR_FALSE) ? true : false;
+ if (!keep_running_)
+ break;
+
+ did_work |= aDelegate->DoWork();
+ if (!keep_running_)
+ break;
+
+ did_work |= aDelegate->DoDelayedWork(&delayed_work_time_);
+ if (!keep_running_)
+ break;
+
+ if (did_work)
+ continue;
+
+ did_work = aDelegate->DoIdleWork();
+ if (!keep_running_)
+ break;
+
+ if (did_work)
+ continue;
+
+ if (delayed_work_time_.is_null()) {
+ event_.Wait();
+ } else {
+ base::TimeDelta delay = delayed_work_time_ - base::Time::Now();
+ if (delay > base::TimeDelta()) {
+ event_.TimedWait(delay);
+ } else {
+ // It looks like delayed_work_time_ indicates a time in the past, so we
+ // need to call DoDelayedWork now.
+ delayed_work_time_ = base::Time();
+ }
+ }
+ // Since event_ is auto-reset, we don't need to do anything special here
+ // other than service each delegate method.
+ }
+
+ threadInternal->SetObserver(realObserver);
+
+ keep_running_ = true;
+}
+
+#ifdef DEBUG
+namespace {
+MessagePump::Delegate* gFirstDelegate = nsnull;
+}
+#endif
+
+void
+MessagePumpForChildProcess::Run(MessagePump::Delegate* aDelegate)
+{
+ if (mFirstRun) {
+#ifdef DEBUG
+ NS_ASSERTION(aDelegate && gFirstDelegate == nsnull, "Huh?!");
+ gFirstDelegate = aDelegate;
+#endif
+ mFirstRun = false;
+ nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
+ NS_WARN_IF_FALSE(appShell, "Failed to get app shell?!");
+ if (appShell) {
+ nsresult rv = appShell->Run();
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Failed to run app shell?!");
+ }
+ }
+#ifdef DEBUG
+ NS_ASSERTION(aDelegate && aDelegate == gFirstDelegate, "Huh?!");
+ gFirstDelegate = nsnull;
+#endif
+ return;
+ }
+#ifdef DEBUG
+ NS_ASSERTION(aDelegate && aDelegate == gFirstDelegate, "Huh?!");
+#endif
+ mozilla::ipc::MessagePump::Run(aDelegate);
+}
new file mode 100644
--- /dev/null
+++ b/ipc/glue/MessagePump.h
@@ -0,0 +1,69 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPC.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __IPC_GLUE_MESSAGEPUMP_H__
+#define __IPC_GLUE_MESSAGEPUMP_H__
+
+#include "base/message_pump_default.h"
+
+namespace mozilla {
+namespace ipc {
+
+class MessagePump : public base::MessagePumpDefault
+{
+public:
+ friend class UIThreadObserver;
+
+ virtual void Run(base::MessagePump::Delegate* aDelegate);
+};
+
+class MessagePumpForChildProcess : public MessagePump
+{
+public:
+ MessagePumpForChildProcess()
+ : mFirstRun(true)
+ { }
+
+ virtual void Run(base::MessagePump::Delegate* aDelegate);
+
+private:
+ bool mFirstRun;
+};
+
+} /* namespace ipc */
+} /* namespace mozilla */
+
+#endif /* __IPC_GLUE_MESSAGEPUMP_H__ */
new file mode 100644
--- /dev/null
+++ b/ipc/glue/MessageTypes.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: sw=4 ts=4 et :
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ * Chris Jones <jones.chris.g@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_ipc_MessageTypes_h
+#define mozilla_ipc_MessageTypes_h 1
+
+// FIXME/cjones: maybe not the best basic types in the long run. what else?
+#include <string>
+#include <vector>
+
+namespace mozilla {
+namespace ipc {
+
+typedef std::string String;
+typedef std::vector<String> StringArray;
+
+} // namespace ipc
+} // namespace mozilla
+
+#endif // ifndef mozilla_ipc_MessageTypes_h
new file mode 100644
--- /dev/null
+++ b/ipc/glue/RPCChannel.cpp
@@ -0,0 +1,231 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: sw=4 ts=4 et :
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ * Chris Jones <jones.chris.g@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mozilla/ipc/GeckoThread.h"
+#include "mozilla/ipc/RPCChannel.h"
+
+#include "nsDebug.h"
+
+using mozilla::MutexAutoLock;
+
+template<>
+struct RunnableMethodTraits<mozilla::ipc::RPCChannel>
+{
+ static void RetainCallee(mozilla::ipc::RPCChannel* obj) { }
+ static void ReleaseCallee(mozilla::ipc::RPCChannel* obj) { }
+};
+
+namespace mozilla {
+namespace ipc {
+
+
+bool
+RPCChannel::Open(Transport* aTransport, MessageLoop* aIOLoop)
+{
+ NS_PRECONDITION(!mTransport, "Open() called > once");
+ NS_PRECONDITION(aTransport, "need transport layer");
+
+ // FIXME need to check for valid channel
+
+ mTransport = aTransport;
+ mTransport->set_listener(this);
+
+ // FIXME do away with this
+ bool needOpen = true;
+ if(!aIOLoop) {
+ needOpen = false;
+ aIOLoop = BrowserProcessSubThread
+ ::GetMessageLoop(BrowserProcessSubThread::IO);
+ }
+
+ mIOLoop = aIOLoop;
+ mWorkerLoop = MessageLoop::current();
+
+ NS_ASSERTION(mIOLoop, "need an IO loop");
+ NS_ASSERTION(mWorkerLoop, "need a worker loop");
+
+ if (needOpen) {
+ mIOLoop->PostTask(FROM_HERE,
+ NewRunnableMethod(this,
+ &RPCChannel::OnChannelOpened));
+ }
+
+ return true;
+}
+
+void
+RPCChannel::Close()
+{
+ // FIXME impl
+
+ mChannelState = ChannelClosed;
+}
+
+bool
+RPCChannel::Call(Message* msg, Message* reply)
+{
+ mMutex.Lock();
+
+ mPending.push(*msg);
+ mIOLoop->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &RPCChannel::SendCall,
+ msg));
+ while (1) {
+ // here we're waiting for something to happen. it may either
+ // be a reply to an outstanding message, or a recursive call
+ // from the other side
+ mCvar.Wait();
+
+ Message recvd = mPending.top();
+ mPending.pop();
+
+ if (recvd.is_reply()) {
+ // we received a reply to our most recent message. pop this
+ // frame and return the reply
+ NS_ASSERTION(0 < mPending.size(), "invalid RPC stack");
+ mPending.pop();
+ *reply = recvd;
+
+ mMutex.Unlock();
+ return true;
+ }
+ else {
+ mMutex.Unlock();
+
+ // someone called in to us from the other side. handle the call
+ if (!ProcessIncomingCall(recvd))
+ return false;
+
+ mMutex.Lock();
+ }
+ }
+
+ delete msg;
+
+ return true;
+}
+
+bool
+RPCChannel::ProcessIncomingCall(Message call)
+{
+ Message* reply;
+
+ switch (mListener->OnCallReceived(call, &reply)) {
+ case Listener::MsgProcessed:
+ mIOLoop->PostTask(FROM_HERE,
+ NewRunnableMethod(this,
+ &RPCChannel::SendReply,
+ reply));
+ return true;
+
+ case Listener::MsgNotKnown:
+ case Listener::MsgNotAllowed:
+ //OnError()?
+ return false;
+
+ default:
+ NOTREACHED();
+ return false;
+ }
+}
+
+void
+RPCChannel::OnIncomingCall(Message msg)
+{
+ NS_ASSERTION(0 == mPending.size(),
+ "woke up the worker thread when it had outstanding work!");
+ ProcessIncomingCall(msg);
+}
+
+//
+// The methods below run in the context of the IO thread, and can proxy
+// back to the methods above
+//
+
+void
+RPCChannel::OnMessageReceived(const Message& msg)
+{MutexAutoLock lock(mMutex);
+ if (0 == mPending.size()) {
+ // wake up the worker, there's work to do
+ mWorkerLoop->PostTask(FROM_HERE,
+ NewRunnableMethod(this,
+ &RPCChannel::OnIncomingCall,
+ msg));
+ }
+ else {
+ // let the worker know something new has happened
+ mPending.push(msg);
+ mCvar.Notify();
+ }
+}
+
+void
+RPCChannel::OnChannelConnected(int peer_pid)
+{
+ mChannelState = ChannelConnected;
+}
+
+void
+RPCChannel::OnChannelError()
+{
+ // FIXME/cjones impl
+ mChannelState = ChannelError;
+}
+
+void
+RPCChannel::OnChannelOpened()
+{
+ mChannelState = ChannelOpening;
+ /*assert*/mTransport->Connect();
+}
+
+void
+RPCChannel::SendCall(Message* aCall)
+{
+ mTransport->Send(aCall);
+}
+
+void
+RPCChannel::SendReply(Message* aReply)
+{
+ mTransport->Send(aReply);
+}
+
+
+} // namespace ipc
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/ipc/glue/RPCChannel.h
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: sw=4 ts=4 et :
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ * Chris Jones <jones.chris.g@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef ipc_glue_RPCChannel_h
+#define ipc_glue_RPCChannel_h 1
+
+// FIXME/cjones probably shouldn't depend on this
+#include <stack>
+
+#include "base/message_loop.h"
+#include "chrome/common/ipc_channel.h"
+
+#include "mozilla/CondVar.h"
+#include "mozilla/Mutex.h"
+
+namespace mozilla {
+namespace ipc {
+//-----------------------------------------------------------------------------
+
+class RPCChannel : public IPC::Channel::Listener
+{
+private:
+ typedef mozilla::CondVar CondVar;
+ typedef mozilla::Mutex Mutex;
+
+ enum ChannelState {
+ ChannelClosed,
+ ChannelOpening,
+ ChannelConnected,
+ ChannelError
+ };
+
+public:
+ typedef IPC::Channel Transport;
+ typedef IPC::Message Message;
+
+ class Listener
+ {
+ public:
+ enum Result {
+ // We processed the message, and it can be forgotten
+ MsgProcessed,
+ // We haven't heard of this message type
+ MsgNotKnown,
+ // We weren't in a state to receive this message
+ MsgNotAllowed
+ };
+
+ virtual ~Listener() { }
+ virtual Result OnCallReceived(const Message& aMessage,
+ Message** aReply) = 0;
+ };
+
+ /**
+ * Convert the asynchronous channel |aChannel| into a channel with
+ * RPC semantics. Received messages are passed down to
+ * |aListener|.
+ *
+ * FIXME do away with |aMode|
+ */
+ RPCChannel(Listener* aListener) :
+ mTransport(0),
+ mListener(aListener),
+ mChannelState(ChannelClosed),
+ mMutex("mozilla.ipc.RPCChannel.mMutex"),
+ mCvar(mMutex, "mozilla.ipc.RPCChannel.mCvar")
+ {
+ }
+
+ virtual ~RPCChannel()
+ {
+ if (mTransport)
+ Close();
+ mTransport = 0;
+ }
+
+ // Open from the perspective of the RPC layer; the transport
+ // should already be connected, or ready to connect.
+ bool Open(Transport* aTransport, MessageLoop* aIOLoop=0);
+
+ // Close from the perspective of the RPC layer; leaves the
+ // underlying transport channel open, however.
+ void Close();
+
+ // Implement the IPC::Channel::Listener interface
+ virtual void OnMessageReceived(const Message& msg);
+ virtual void OnChannelConnected(int32 peer_pid);
+ virtual void OnChannelError();
+
+ // Make an RPC to the other side of the channel
+ virtual bool Call(Message* msg, Message* reply);
+
+private:
+ // Task created when we're idle (wrt this channel), and the other
+ // side has made an RPC to us
+ void OnIncomingCall(Message msg);
+ // Process an RPC made from the other side to here
+ bool ProcessIncomingCall(Message msg);
+
+ void OnChannelOpened();
+ void SendCall(Message* aCall);
+ void SendReply(Message* aReply);
+
+ Transport* mTransport;
+ Listener* mListener;
+ ChannelState mChannelState;
+ MessageLoop* mIOLoop; // thread where IO happens
+ MessageLoop* mWorkerLoop; // thread where work is done
+ Mutex mMutex;
+ CondVar mCvar;
+ std::stack<Message> mPending;
+};
+
+
+} // namespace ipc
+} // namespace mozilla
+#endif // ifndef ipc_glue_RPCChannel_h
new file mode 100644
--- /dev/null
+++ b/ipc/glue/ScopedXREEmbed.cpp
@@ -0,0 +1,91 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "ScopedXREEmbed.h"
+
+#include "base/command_line.h"
+#include "base/string_util.h"
+
+#include "nsIFile.h"
+#include "nsILocalFile.h"
+
+#include "nsCOMPtr.h"
+#include "nsServiceManagerUtils.h"
+#include "nsStringGlue.h"
+#include "nsXULAppAPI.h"
+
+using mozilla::ipc::ScopedXREEmbed;
+
+ScopedXREEmbed::ScopedXREEmbed()
+: mShouldKillEmbedding(false)
+{
+}
+
+ScopedXREEmbed::~ScopedXREEmbed()
+{
+ Stop();
+}
+
+void
+ScopedXREEmbed::Start()
+{
+ std::string path = WideToUTF8(CommandLine::ForCurrentProcess()->program());
+
+ nsCOMPtr<nsILocalFile> localFile;
+ nsresult rv = XRE_GetBinaryPath(path.c_str(), getter_AddRefs(localFile));
+ NS_ENSURE_SUCCESS(rv,);
+
+ nsCOMPtr<nsIFile> parent;
+ rv = localFile->GetParent(getter_AddRefs(parent));
+ NS_ENSURE_SUCCESS(rv,);
+
+ localFile = do_QueryInterface(parent);
+ NS_ENSURE_TRUE(localFile,);
+
+ rv = XRE_InitEmbedding(localFile, localFile, nsnull, nsnull, 0);
+ NS_ENSURE_SUCCESS(rv,);
+
+ mShouldKillEmbedding = true;
+}
+
+void
+ScopedXREEmbed::Stop()
+{
+ if (mShouldKillEmbedding) {
+ XRE_TermEmbedding();
+ mShouldKillEmbedding = false;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/ipc/glue/ScopedXREEmbed.h
@@ -0,0 +1,59 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ * Ben Turner <bent.mozilla@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __IPC_GLUE_SCOPEDXREEMBED_H__
+#define __IPC_GLUE_SCOPEDXREEMBED_H__
+
+namespace mozilla {
+namespace ipc {
+
+class ScopedXREEmbed
+{
+public:
+ ScopedXREEmbed();
+ ~ScopedXREEmbed();
+
+ void Start();
+ void Stop();
+
+private:
+ bool mShouldKillEmbedding;
+};
+
+} /* namespace ipc */
+} /* namespace mozilla */
+
+#endif /* __IPC_GLUE_SCOPEDXREEMBED_H__ */
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/ipc/glue/StringUtil.cpp
@@ -0,0 +1,153 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPC.
+ *
+ * The Initial Developer of the Original Code is
+ * Chris Jones <jones.chris.g@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "base/string_util.h"
+
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/sys_string_conversions.h"
+
+#include "base/string_piece.h"
+#include "base/string_util.h"
+
+#include "build/build_config.h"
+
+// FIXME/cjones: these really only pertain to the linux sys string
+// converters.
+#ifdef WCHAR_T_IS_UTF16
+# define ICONV_WCHAR_T_ENCODING "UTF-16"
+#else
+# define ICONV_WCHAR_T_ENCODING "WCHAR_T"
+#endif
+
+// FIXME/cjones: BIG assumption here that std::string is a good
+// container of UTF8-encoded strings. this is probably wrong, as its
+// API doesn't really make sense for UTF8.
+
+namespace base {
+string16 SysWideToUTF16(const std::wstring& wide);
+
+// FIXME/cjones: as its name implies, this function is a hack.
+template<typename FromType, typename ToType>
+ToType
+GhettoStringConvert(const FromType& in)
+{
+ // FIXME/cjones: assumes no non-ASCII characters in |in|
+ ToType out;
+ out.resize(in.length());
+ for (int i = 0; i < static_cast<int>(in.length()); ++i)
+ out[i] = static_cast<typename ToType::value_type>(in[i]);
+ return out;
+}
+}
+
+// Implement functions that were in the chromium ICU library, which
+// we're not taking.
+
+std::string
+WideToUTF8(const std::wstring& wide)
+{
+ return base::SysWideToUTF8(wide);
+}
+
+string16
+UTF8ToUTF16(const std::string& utf8)
+{
+ // FIXME/cjones: do proper conversion
+ return base::GhettoStringConvert<std::string, string16>(utf8);
+}
+
+std::wstring
+UTF8ToWide(const StringPiece& utf8)
+{
+ return base::SysUTF8ToWide(utf8);
+}
+
+string16
+WideToUTF16(const std::wstring& wide)
+{
+ return base::SysWideToUTF16(wide);
+}
+
+std::string
+UTF16ToUTF8(const string16& utf16)
+{
+ // FIXME/cjones: do proper conversion
+ return base::GhettoStringConvert<string16, std::string>(utf16);
+}
+
+namespace base {
+
+// FIXME/cjones: here we're entirely replacing the linux string
+// converters, and implementing the one that doesn't exist for OS X.
+
+#ifndef OS_MACOSX
+std::string SysWideToUTF8(const std::wstring& wide) {
+ // FIXME/cjones: do this with iconv
+ return GhettoStringConvert<std::wstring, std::string>(wide);
+}
+#endif
+
+string16 SysWideToUTF16(const std::wstring& wide)
+{
+#if defined(WCHAR_T_IS_UTF16)
+ return wide;
+#else
+ // FIXME/cjones: do this with iconv for linux, other for OS X
+ return GhettoStringConvert<std::wstring, string16>(wide);
+#endif
+}
+
+#ifndef OS_MACOSX
+std::wstring SysUTF8ToWide(const StringPiece& utf8) {
+ // FIXME/cjones: do this with iconv
+ return GhettoStringConvert<StringPiece, std::wstring>(utf8);
+}
+
+std::string SysWideToNativeMB(const std::wstring& wide) {
+ // TODO(evanm): we can't assume Linux is UTF-8.
+ return SysWideToUTF8(wide);
+}
+
+std::wstring SysNativeMBToWide(const StringPiece& native_mb) {
+ // TODO(evanm): we can't assume Linux is UTF-8.
+ return SysUTF8ToWide(native_mb);
+}
+#endif
+
+} // namespace base