summaryrefslogtreecommitdiffstats
path: root/dom/plugins/ipc/hangui/MiniShmBase.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /dom/plugins/ipc/hangui/MiniShmBase.h
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/plugins/ipc/hangui/MiniShmBase.h')
-rw-r--r--dom/plugins/ipc/hangui/MiniShmBase.h280
1 files changed, 280 insertions, 0 deletions
diff --git a/dom/plugins/ipc/hangui/MiniShmBase.h b/dom/plugins/ipc/hangui/MiniShmBase.h
new file mode 100644
index 0000000000..9782330b12
--- /dev/null
+++ b/dom/plugins/ipc/hangui/MiniShmBase.h
@@ -0,0 +1,280 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=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_plugins_MiniShmBase_h
+#define mozilla_plugins_MiniShmBase_h
+
+#include "base/basictypes.h"
+
+#include "nsDebug.h"
+
+#include <windows.h>
+
+namespace mozilla {
+namespace plugins {
+
+/**
+ * This class is used to provide RAII semantics for mapped views.
+ * @see ScopedHandle
+ */
+class ScopedMappedFileView {
+ public:
+ explicit ScopedMappedFileView(LPVOID aView) : mView(aView) {}
+
+ ~ScopedMappedFileView() { Close(); }
+
+ void Close() {
+ if (mView) {
+ ::UnmapViewOfFile(mView);
+ mView = nullptr;
+ }
+ }
+
+ void Set(LPVOID aView) {
+ Close();
+ mView = aView;
+ }
+
+ LPVOID
+ Get() const { return mView; }
+
+ LPVOID
+ Take() {
+ LPVOID result = mView;
+ mView = nullptr;
+ return result;
+ }
+
+ operator LPVOID() { return mView; }
+
+ bool IsValid() const { return (mView); }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScopedMappedFileView);
+
+ LPVOID mView;
+};
+
+class MiniShmBase;
+
+class MiniShmObserver {
+ public:
+ /**
+ * This function is called whenever there is a new shared memory request.
+ * @param aMiniShmObj MiniShmBase object that may be used to read and
+ * write from shared memory.
+ */
+ virtual void OnMiniShmEvent(MiniShmBase* aMiniShmObj) = 0;
+ /**
+ * This function is called once when a MiniShmParent and a MiniShmChild
+ * object have successfully negotiated a connection.
+ *
+ * @param aMiniShmObj MiniShmBase object that may be used to read and
+ * write from shared memory.
+ */
+ virtual void OnMiniShmConnect(MiniShmBase* aMiniShmObj) {}
+};
+
+/**
+ * Base class for MiniShm connections. This class defines the common
+ * interfaces and code between parent and child.
+ */
+class MiniShmBase {
+ public:
+ /**
+ * Obtains a writable pointer into shared memory of type T.
+ * typename T must be plain-old-data and contain an unsigned integral
+ * member T::identifier that uniquely identifies T with respect to
+ * other types used by the protocol being implemented.
+ *
+ * @param aPtr Pointer to receive the shared memory address.
+ * This value is set if and only if the function
+ * succeeded.
+ * @return NS_OK if and only if aPtr was successfully obtained.
+ * NS_ERROR_ILLEGAL_VALUE if type T is not valid for MiniShm.
+ * NS_ERROR_NOT_INITIALIZED if there is no valid MiniShm connection.
+ * NS_ERROR_NOT_AVAILABLE if the memory is not safe to write.
+ */
+ template <typename T>
+ nsresult GetWritePtr(T*& aPtr) {
+ if (!mWriteHeader || !mGuard) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ if (sizeof(T) > mPayloadMaxLen ||
+ (int)T::identifier <= (int)RESERVED_CODE_LAST) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ if (::WaitForSingleObject(mGuard, mTimeout) != WAIT_OBJECT_0) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ mWriteHeader->mId = T::identifier;
+ mWriteHeader->mPayloadLen = sizeof(T);
+ aPtr = reinterpret_cast<T*>(mWriteHeader + 1);
+ return NS_OK;
+ }
+
+ /**
+ * Obtains a readable pointer into shared memory of type T.
+ * typename T must be plain-old-data and contain an unsigned integral
+ * member T::identifier that uniquely identifies T with respect to
+ * other types used by the protocol being implemented.
+ *
+ * @param aPtr Pointer to receive the shared memory address.
+ * This value is set if and only if the function
+ * succeeded.
+ * @return NS_OK if and only if aPtr was successfully obtained.
+ * NS_ERROR_ILLEGAL_VALUE if type T is not valid for MiniShm or if
+ * type T does not match the type of the data
+ * stored in shared memory.
+ * NS_ERROR_NOT_INITIALIZED if there is no valid MiniShm connection.
+ */
+ template <typename T>
+ nsresult GetReadPtr(const T*& aPtr) {
+ if (!mReadHeader) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ if (mReadHeader->mId != T::identifier ||
+ sizeof(T) != mReadHeader->mPayloadLen) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aPtr = reinterpret_cast<const T*>(mReadHeader + 1);
+ return NS_OK;
+ }
+
+ /**
+ * Fires the peer's event causing its request handler to execute.
+ *
+ * @return Should return NS_OK if the send was successful.
+ */
+ virtual nsresult Send() = 0;
+
+ protected:
+ /**
+ * MiniShm reserves some identifier codes for its own use. Any
+ * identifiers used by MiniShm protocol implementations must be
+ * greater than RESERVED_CODE_LAST.
+ */
+ enum ReservedCodes {
+ RESERVED_CODE_INIT = 0,
+ RESERVED_CODE_INIT_COMPLETE = 1,
+ RESERVED_CODE_LAST = RESERVED_CODE_INIT_COMPLETE
+ };
+
+ struct MiniShmHeader {
+ unsigned int mId;
+ unsigned int mPayloadLen;
+ };
+
+ struct MiniShmInit {
+ enum identifier_t { identifier = RESERVED_CODE_INIT };
+ HANDLE mParentEvent;
+ HANDLE mParentGuard;
+ HANDLE mChildEvent;
+ HANDLE mChildGuard;
+ };
+
+ struct MiniShmInitComplete {
+ enum identifier_t { identifier = RESERVED_CODE_INIT_COMPLETE };
+ bool mSucceeded;
+ };
+
+ MiniShmBase()
+ : mObserver(nullptr),
+ mWriteHeader(nullptr),
+ mReadHeader(nullptr),
+ mPayloadMaxLen(0),
+ mGuard(nullptr),
+ mTimeout(INFINITE) {}
+ virtual ~MiniShmBase() {}
+
+ virtual void OnEvent() {
+ if (mObserver) {
+ mObserver->OnMiniShmEvent(this);
+ }
+ }
+
+ virtual void OnConnect() {
+ if (mObserver) {
+ mObserver->OnMiniShmConnect(this);
+ }
+ }
+
+ nsresult SetView(LPVOID aView, const unsigned int aSize, bool aIsChild) {
+ if (!aView || aSize <= 2 * sizeof(MiniShmHeader)) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ // Divide the region into halves for parent and child
+ if (aIsChild) {
+ mReadHeader = static_cast<MiniShmHeader*>(aView);
+ mWriteHeader = reinterpret_cast<MiniShmHeader*>(
+ static_cast<char*>(aView) + aSize / 2U);
+ } else {
+ mWriteHeader = static_cast<MiniShmHeader*>(aView);
+ mReadHeader = reinterpret_cast<MiniShmHeader*>(static_cast<char*>(aView) +
+ aSize / 2U);
+ }
+ mPayloadMaxLen = aSize / 2U - sizeof(MiniShmHeader);
+ return NS_OK;
+ }
+
+ nsresult SetGuard(HANDLE aGuard, DWORD aTimeout) {
+ if (!aGuard || !aTimeout) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ mGuard = aGuard;
+ mTimeout = aTimeout;
+ return NS_OK;
+ }
+
+ inline void SetObserver(MiniShmObserver* aObserver) { mObserver = aObserver; }
+
+ /**
+ * Obtains a writable pointer into shared memory of type T. This version
+ * differs from GetWritePtr in that it allows typename T to be one of
+ * the private data structures declared in MiniShmBase.
+ *
+ * @param aPtr Pointer to receive the shared memory address.
+ * This value is set if and only if the function
+ * succeeded.
+ * @return NS_OK if and only if aPtr was successfully obtained.
+ * NS_ERROR_ILLEGAL_VALUE if type T not an internal MiniShm struct.
+ * NS_ERROR_NOT_INITIALIZED if there is no valid MiniShm connection.
+ */
+ template <typename T>
+ nsresult GetWritePtrInternal(T*& aPtr) {
+ if (!mWriteHeader) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ if (sizeof(T) > mPayloadMaxLen ||
+ (int)T::identifier > (int)RESERVED_CODE_LAST) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ mWriteHeader->mId = T::identifier;
+ mWriteHeader->mPayloadLen = sizeof(T);
+ aPtr = reinterpret_cast<T*>(mWriteHeader + 1);
+ return NS_OK;
+ }
+
+ static VOID CALLBACK SOnEvent(PVOID aContext, BOOLEAN aIsTimer) {
+ MiniShmBase* object = static_cast<MiniShmBase*>(aContext);
+ object->OnEvent();
+ }
+
+ private:
+ MiniShmObserver* mObserver;
+ MiniShmHeader* mWriteHeader;
+ MiniShmHeader* mReadHeader;
+ unsigned int mPayloadMaxLen;
+ HANDLE mGuard;
+ DWORD mTimeout;
+
+ DISALLOW_COPY_AND_ASSIGN(MiniShmBase);
+};
+
+} // namespace plugins
+} // namespace mozilla
+
+#endif // mozilla_plugins_MiniShmBase_h