summaryrefslogtreecommitdiffstats
path: root/ipc/glue/SharedMemory.h
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/glue/SharedMemory.h')
-rw-r--r--ipc/glue/SharedMemory.h152
1 files changed, 152 insertions, 0 deletions
diff --git a/ipc/glue/SharedMemory.h b/ipc/glue/SharedMemory.h
new file mode 100644
index 000000000..82f89ae4b
--- /dev/null
+++ b/ipc/glue/SharedMemory.h
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_ipc_SharedMemory_h
+#define mozilla_ipc_SharedMemory_h
+
+#include "nsDebug.h"
+#include "nsISupportsImpl.h" // NS_INLINE_DECL_REFCOUNTING
+#include "mozilla/Attributes.h"
+
+#include "base/process.h"
+#include "chrome/common/ipc_message_utils.h"
+
+//
+// This is a low-level wrapper around platform shared memory. Don't
+// use it directly; use Shmem allocated through IPDL interfaces.
+//
+namespace {
+enum Rights {
+ RightsNone = 0,
+ RightsRead = 1 << 0,
+ RightsWrite = 1 << 1
+};
+} // namespace
+
+namespace mozilla {
+
+namespace ipc {
+class SharedMemory;
+} // namespace ipc
+
+namespace ipc {
+
+class SharedMemory
+{
+protected:
+ virtual ~SharedMemory()
+ {
+ Unmapped();
+ Destroyed();
+ }
+
+public:
+ enum SharedMemoryType {
+ TYPE_BASIC,
+ TYPE_UNKNOWN
+ };
+
+ size_t Size() const { return mMappedSize; }
+
+ virtual void* memory() const = 0;
+
+ virtual bool Create(size_t size) = 0;
+ virtual bool Map(size_t nBytes) = 0;
+
+ virtual void CloseHandle() = 0;
+
+ virtual SharedMemoryType Type() const = 0;
+
+ virtual bool ShareHandle(base::ProcessId aProcessId, IPC::Message* aMessage) = 0;
+ virtual bool ReadHandle(const IPC::Message* aMessage, PickleIterator* aIter) = 0;
+
+ void
+ Protect(char* aAddr, size_t aSize, int aRights)
+ {
+ char* memStart = reinterpret_cast<char*>(memory());
+ if (!memStart)
+ NS_RUNTIMEABORT("SharedMemory region points at NULL!");
+ char* memEnd = memStart + Size();
+
+ char* protStart = aAddr;
+ if (!protStart)
+ NS_RUNTIMEABORT("trying to Protect() a NULL region!");
+ char* protEnd = protStart + aSize;
+
+ if (!(memStart <= protStart
+ && protEnd <= memEnd))
+ NS_RUNTIMEABORT("attempt to Protect() a region outside this SharedMemory");
+
+ // checks alignment etc.
+ SystemProtect(aAddr, aSize, aRights);
+ }
+
+ // bug 1168843, compositor thread may create shared memory instances that are destroyed by main thread on shutdown, so this must use thread-safe RC to avoid hitting assertion
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedMemory)
+
+ static void SystemProtect(char* aAddr, size_t aSize, int aRights);
+ static size_t SystemPageSize();
+ static size_t PageAlignedSize(size_t aSize);
+
+protected:
+ SharedMemory();
+
+ // Implementations should call these methods on shmem usage changes,
+ // but *only if* the OS-specific calls are known to have succeeded.
+ // The methods are expected to be called in the pattern
+ //
+ // Created (Mapped Unmapped)* Destroy
+ //
+ // but this isn't checked.
+ void Created(size_t aNBytes);
+ void Mapped(size_t aNBytes);
+ void Unmapped();
+ void Destroyed();
+
+ // The size of the shmem region requested in Create(), if
+ // successful. SharedMemory instances that are opened from a
+ // foreign handle have an alloc size of 0, even though they have
+ // access to the alloc-size information.
+ size_t mAllocSize;
+ // The size of the region mapped in Map(), if successful. All
+ // SharedMemorys that are mapped have a non-zero mapped size.
+ size_t mMappedSize;
+};
+
+template<typename HandleImpl>
+class SharedMemoryCommon : public SharedMemory
+{
+public:
+ typedef HandleImpl Handle;
+
+ virtual bool ShareToProcess(base::ProcessId aProcessId, Handle* aHandle) = 0;
+ virtual bool IsHandleValid(const Handle& aHandle) const = 0;
+ virtual bool SetHandle(const Handle& aHandle) = 0;
+
+ virtual bool ShareHandle(base::ProcessId aProcessId, IPC::Message* aMessage) override
+ {
+ Handle handle;
+ if (!ShareToProcess(aProcessId, &handle)) {
+ return false;
+ }
+ IPC::WriteParam(aMessage, handle);
+ return true;
+ }
+
+ virtual bool ReadHandle(const IPC::Message* aMessage, PickleIterator* aIter) override
+ {
+ Handle handle;
+ return IPC::ReadParam(aMessage, aIter, &handle) &&
+ IsHandleValid(handle) &&
+ SetHandle(handle);
+ }
+};
+
+} // namespace ipc
+} // namespace mozilla
+
+
+#endif // ifndef mozilla_ipc_SharedMemory_h