Bug 564086, part p: Library support of |bridge| API. r=bent
authorChris Jones <jones.chris.g@gmail.com>
Fri, 03 Jun 2011 13:33:56 -0500
changeset 70536 d11b3f7ed46aa0ca0ba48afde08ab2e8a14a7c21
parent 70535 6588b377a600705e7bfffa8a1412646c47eeebe4
child 70537 3bc8c3c8b75304e2f9c40b9e3ca29115ae63a88b
push idunknown
push userunknown
push dateunknown
reviewersbent
bugs564086
milestone7.0a1
Bug 564086, part p: Library support of |bridge| API. r=bent
ipc/glue/Makefile.in
ipc/glue/ProtocolUtils.cpp
ipc/glue/ProtocolUtils.h
ipc/glue/Transport.h
ipc/glue/Transport_posix.cpp
ipc/glue/Transport_win.cpp
--- a/ipc/glue/Makefile.in
+++ b/ipc/glue/Makefile.in
@@ -92,16 +92,17 @@ EXPORTS_mozilla/ipc += SharedMemoryBasic
 endif #}
 
 CPPSRCS += \
   AsyncChannel.cpp \
   BrowserProcessSubThread.cpp \
   GeckoChildProcessHost.cpp \
   MessagePump.cpp \
   ProcessChild.cpp \
+  ProtocolUtils.cpp \
   RPCChannel.cpp \
   ScopedXREEmbed.cpp \
   SharedMemory.cpp \
   Shmem.cpp \
   StringUtil.cpp \
   SyncChannel.cpp \
   $(NULL)
 
new file mode 100644
--- /dev/null
+++ b/ipc/glue/ProtocolUtils.cpp
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=8 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 Code.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Chris Jones <jones.chris.g@gmail.com>
+ *
+ * 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/process_util.h"
+
+#include "mozilla/ipc/AsyncChannel.h"
+#include "mozilla/ipc/ProtocolUtils.h"
+#include "mozilla/ipc/Transport.h"
+
+using namespace base;
+
+namespace mozilla {
+namespace ipc {
+
+class ChannelOpened : public IPC::Message
+{
+public:
+  ChannelOpened(TransportDescriptor aDescriptor,
+                ProcessId aOtherProcess,
+                ProtocolId aProtocol)
+    : IPC::Message(MSG_ROUTING_CONTROL, // these only go to top-level actors
+                   CHANNEL_OPENED_MESSAGE_TYPE,
+                   PRIORITY_NORMAL)
+  {
+    IPC::WriteParam(this, aDescriptor);
+    IPC::WriteParam(this, aOtherProcess);
+    IPC::WriteParam(this, static_cast<uint32>(aProtocol));
+  }
+
+  static bool Read(const IPC::Message& aMsg,
+                   TransportDescriptor* aDescriptor,
+                   ProcessId* aOtherProcess,
+                   ProtocolId* aProtocol)
+  {
+    void* iter = nsnull;
+    if (!IPC::ReadParam(&aMsg, &iter, aDescriptor) ||
+        !IPC::ReadParam(&aMsg, &iter, aOtherProcess) ||
+        !IPC::ReadParam(&aMsg, &iter, reinterpret_cast<uint32*>(aProtocol))) {
+      return false;
+    }
+    aMsg.EndRead(iter);
+    return true;
+  }
+};
+
+bool
+Bridge(const PrivateIPDLInterface&,
+       AsyncChannel* aParentChannel, ProcessHandle aParentProcess,
+       AsyncChannel* aChildChannel, ProcessHandle aChildProcess,
+       ProtocolId aProtocol)
+{
+  ProcessId parentId = GetProcId(aParentProcess);
+  ProcessId childId = GetProcId(aChildProcess);
+  if (!parentId || !childId) {
+    return false;
+  }
+
+  TransportDescriptor parentSide, childSide;
+  if (!CreateTransport(aParentProcess, aChildProcess,
+                       &parentSide, &childSide)) {
+    return false;
+  }
+
+  if (!aParentChannel->Send(new ChannelOpened(parentSide,
+                                              childId,
+                                              aProtocol)) ||
+      !aChildChannel->Send(new ChannelOpened(childSide,
+                                             parentId,
+                                             aProtocol))) {
+    CloseDescriptor(parentSide);
+    CloseDescriptor(childSide);
+    return false;
+  }
+  return true;
+}
+
+bool
+UnpackChannelOpened(const PrivateIPDLInterface&,
+                    const IPC::Message& aMsg,
+                    TransportDescriptor* aTransport,
+                    ProcessId* aOtherProcess,
+                    ProtocolId* aProtocol)
+{
+  return ChannelOpened::Read(aMsg, aTransport, aOtherProcess, aProtocol);
+}
+
+} // namespace ipc
+} // namespace mozilla
--- a/ipc/glue/ProtocolUtils.h
+++ b/ipc/glue/ProtocolUtils.h
@@ -41,22 +41,31 @@
 #define mozilla_ipc_ProtocolUtils_h 1
 
 #include "base/process.h"
 #include "base/process_util.h"
 #include "chrome/common/ipc_message_utils.h"
 
 #include "prenv.h"
 
+#include "IPCMessageStart.h"
 #include "mozilla/ipc/Shmem.h"
+#include "mozilla/ipc/Transport.h"
 
 // WARNING: this takes into account the private, special-message-type
 // enum in ipc_channel.h.  They need to be kept in sync.
 namespace {
+// XXX the max message ID is actually kuint32max now ... when this
+// changed, the assumptions of the special message IDs changed in that
+// they're not carving out messages from likely-unallocated space, but
+// rather carving out messages from the end of space allocated to
+// protocol 0.  Oops!  We can get away with this until protocol 0
+// starts approaching its 65,536th message.
 enum {
+    CHANNEL_OPENED_MESSAGE_TYPE = kuint16max - 6,
     SHMEM_DESTROYED_MESSAGE_TYPE = kuint16max - 5,
     UNBLOCK_CHILD_MESSAGE_TYPE = kuint16max - 4,
     BLOCK_CHILD_MESSAGE_TYPE   = kuint16max - 3,
     SHMEM_CREATED_MESSAGE_TYPE = kuint16max - 2,
     GOODBYE_MESSAGE_TYPE       = kuint16max - 1,
 };
 }
 
@@ -130,16 +139,30 @@ LoggingEnabled()
 #if defined(DEBUG)
     return !!PR_GetEnv("MOZ_IPC_MESSAGE_LOG");
 #else
     return false;
 #endif
 }
 
 
+typedef IPCMessageStart ProtocolId;
+
+struct PrivateIPDLInterface {};
+
+bool
+Bridge(const PrivateIPDLInterface&,
+       AsyncChannel*, base::ProcessHandle, AsyncChannel*, base::ProcessHandle,
+       ProtocolId);
+
+bool
+UnpackChannelOpened(const PrivateIPDLInterface&,
+                    const IPC::Message&,
+                    TransportDescriptor*, base::ProcessId*, ProtocolId*);
+
 } // namespace ipc
 } // namespace mozilla
 
 
 namespace IPC {
 
 template <>
 struct ParamTraits<mozilla::ipc::ActorHandle>
--- a/ipc/glue/Transport.h
+++ b/ipc/glue/Transport.h
@@ -57,13 +57,14 @@ namespace ipc {
 typedef IPC::Channel Transport;
 
 bool CreateTransport(base::ProcessHandle aProcOne, base::ProcessHandle aProcTwo,
                      TransportDescriptor* aOne, TransportDescriptor* aTwo);
 
 Transport* OpenDescriptor(const TransportDescriptor& aTd,
                           Transport::Mode aMode);
 
+void CloseDescriptor(const TransportDescriptor& aTd);
 
 } // namespace ipc
 } // namespace mozilla
 
 #endif  // mozilla_ipc_Transport_h
--- a/ipc/glue/Transport_posix.cpp
+++ b/ipc/glue/Transport_posix.cpp
@@ -83,10 +83,16 @@ CreateTransport(ProcessHandle /*unused*/
 }
 
 Transport*
 OpenDescriptor(const TransportDescriptor& aTd, Transport::Mode aMode)
 {
   return new Transport(aTd.mFd.fd, aMode, nsnull);
 }
 
+void
+CloseDescriptor(const TransportDescriptor& aTd)
+{
+  close(aTd.mFd.fd);
+}
+
 } // namespace ipc
 } // namespace mozilla
--- a/ipc/glue/Transport_win.cpp
+++ b/ipc/glue/Transport_win.cpp
@@ -86,10 +86,16 @@ CreateTransport(ProcessHandle aProcOne, 
 }
 
 Transport*
 OpenDescriptor(const TransportDescriptor& aTd, Transport::Mode aMode)
 {
   return new Transport(aTd.mPipeName, aTd.mServerPipe, aMode, nsnull);
 }
 
+void
+CloseDescriptor(const TransportDescriptor& aTd)
+{
+  CloseHandle(aTd.mServerPipe);
+}
+
 } // namespace ipc
 } // namespace mozilla