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