summaryrefslogtreecommitdiff
path: root/dom/plugins/ipc/MiniShmParent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/plugins/ipc/MiniShmParent.cpp')
-rw-r--r--dom/plugins/ipc/MiniShmParent.cpp217
1 files changed, 217 insertions, 0 deletions
diff --git a/dom/plugins/ipc/MiniShmParent.cpp b/dom/plugins/ipc/MiniShmParent.cpp
new file mode 100644
index 000000000..d3e75ad9c
--- /dev/null
+++ b/dom/plugins/ipc/MiniShmParent.cpp
@@ -0,0 +1,217 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#include "MiniShmParent.h"
+
+#include "base/scoped_handle.h"
+
+#include <sstream>
+
+namespace mozilla {
+namespace plugins {
+
+// static
+const unsigned int MiniShmParent::kDefaultMiniShmSectionSize = 0x1000;
+
+MiniShmParent::MiniShmParent()
+ : mSectionSize(0),
+ mParentEvent(nullptr),
+ mParentGuard(nullptr),
+ mChildEvent(nullptr),
+ mChildGuard(nullptr),
+ mRegWait(nullptr),
+ mFileMapping(nullptr),
+ mView(nullptr),
+ mIsConnected(false),
+ mTimeout(INFINITE)
+{
+}
+
+MiniShmParent::~MiniShmParent()
+{
+ CleanUp();
+}
+
+void
+MiniShmParent::CleanUp()
+{
+ if (mRegWait) {
+ ::UnregisterWaitEx(mRegWait, INVALID_HANDLE_VALUE);
+ mRegWait = nullptr;
+ }
+ if (mParentEvent) {
+ ::CloseHandle(mParentEvent);
+ mParentEvent = nullptr;
+ }
+ if (mParentGuard) {
+ ::CloseHandle(mParentGuard);
+ mParentGuard = nullptr;
+ }
+ if (mChildEvent) {
+ ::CloseHandle(mChildEvent);
+ mChildEvent = nullptr;
+ }
+ if (mChildGuard) {
+ ::CloseHandle(mChildGuard);
+ mChildGuard = nullptr;
+ }
+ if (mView) {
+ ::UnmapViewOfFile(mView);
+ mView = nullptr;
+ }
+ if (mFileMapping) {
+ ::CloseHandle(mFileMapping);
+ mFileMapping = nullptr;
+ }
+}
+
+nsresult
+MiniShmParent::Init(MiniShmObserver* aObserver, const DWORD aTimeout,
+ const unsigned int aSectionSize)
+{
+ if (!aObserver || !aSectionSize || (aSectionSize % 0x1000) || !aTimeout) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ if (mFileMapping) {
+ return NS_ERROR_ALREADY_INITIALIZED;
+ }
+ SECURITY_ATTRIBUTES securityAttributes = {sizeof(securityAttributes),
+ nullptr,
+ TRUE};
+ ScopedHandle parentEvent(::CreateEvent(&securityAttributes,
+ FALSE,
+ FALSE,
+ nullptr));
+ if (!parentEvent.IsValid()) {
+ return NS_ERROR_FAILURE;
+ }
+ ScopedHandle parentGuard(::CreateEvent(&securityAttributes,
+ FALSE,
+ TRUE,
+ nullptr));
+ if (!parentGuard.IsValid()) {
+ return NS_ERROR_FAILURE;
+ }
+ ScopedHandle childEvent(::CreateEvent(&securityAttributes,
+ FALSE,
+ FALSE,
+ nullptr));
+ if (!childEvent.IsValid()) {
+ return NS_ERROR_FAILURE;
+ }
+ ScopedHandle childGuard(::CreateEvent(&securityAttributes,
+ FALSE,
+ TRUE,
+ nullptr));
+ if (!childGuard.IsValid()) {
+ return NS_ERROR_FAILURE;
+ }
+ ScopedHandle mapping(::CreateFileMapping(INVALID_HANDLE_VALUE,
+ &securityAttributes,
+ PAGE_READWRITE,
+ 0,
+ aSectionSize,
+ nullptr));
+ if (!mapping.IsValid()) {
+ return NS_ERROR_FAILURE;
+ }
+ ScopedMappedFileView view(::MapViewOfFile(mapping,
+ FILE_MAP_WRITE,
+ 0, 0, 0));
+ if (!view.IsValid()) {
+ return NS_ERROR_FAILURE;
+ }
+ nsresult rv = SetView(view, aSectionSize, false);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = SetGuard(childGuard, aTimeout);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ MiniShmInit* initStruct = nullptr;
+ rv = GetWritePtrInternal(initStruct);
+ NS_ENSURE_SUCCESS(rv, rv);
+ initStruct->mParentEvent = parentEvent;
+ initStruct->mParentGuard = parentGuard;
+ initStruct->mChildEvent = childEvent;
+ initStruct->mChildGuard = childGuard;
+
+ if (!::RegisterWaitForSingleObject(&mRegWait,
+ parentEvent,
+ &SOnEvent,
+ this,
+ INFINITE,
+ WT_EXECUTEDEFAULT)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ mParentEvent = parentEvent.Take();
+ mParentGuard = parentGuard.Take();
+ mChildEvent = childEvent.Take();
+ mChildGuard = childGuard.Take();
+ mFileMapping = mapping.Take();
+ mView = view.Take();
+ mSectionSize = aSectionSize;
+ SetObserver(aObserver);
+ mTimeout = aTimeout;
+ return NS_OK;
+}
+
+nsresult
+MiniShmParent::GetCookie(std::wstring& cookie)
+{
+ if (!mFileMapping) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ std::wostringstream oss;
+ oss << mFileMapping;
+ if (!oss) {
+ return NS_ERROR_FAILURE;
+ }
+ cookie = oss.str();
+ return NS_OK;
+}
+
+nsresult
+MiniShmParent::Send()
+{
+ if (!mChildEvent) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ if (!::SetEvent(mChildEvent)) {
+ return NS_ERROR_FAILURE;
+ }
+ return NS_OK;
+}
+
+bool
+MiniShmParent::IsConnected() const
+{
+ return mIsConnected;
+}
+
+void
+MiniShmParent::OnEvent()
+{
+ if (mIsConnected) {
+ MiniShmBase::OnEvent();
+ } else {
+ FinalizeConnection();
+ }
+ ::SetEvent(mParentGuard);
+}
+
+void
+MiniShmParent::FinalizeConnection()
+{
+ const MiniShmInitComplete* initCompleteStruct = nullptr;
+ nsresult rv = GetReadPtr(initCompleteStruct);
+ mIsConnected = NS_SUCCEEDED(rv) && initCompleteStruct->mSucceeded;
+ if (mIsConnected) {
+ OnConnect();
+ }
+}
+
+} // namespace plugins
+} // namespace mozilla
+