зеркало из https://github.com/mozilla/gecko-dev.git
179 строки
4.8 KiB
C++
179 строки
4.8 KiB
C++
/* -*- 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/. */
|
|
|
|
#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
|