1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/plugins/ipc/MiniShmParent.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,218 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "MiniShmParent.h" 1.11 + 1.12 +#include "base/scoped_handle.h" 1.13 + 1.14 +#include <sstream> 1.15 + 1.16 +namespace mozilla { 1.17 +namespace plugins { 1.18 + 1.19 +// static 1.20 +const unsigned int MiniShmParent::kDefaultMiniShmSectionSize = 0x1000; 1.21 + 1.22 +MiniShmParent::MiniShmParent() 1.23 + : mSectionSize(0), 1.24 + mParentEvent(nullptr), 1.25 + mParentGuard(nullptr), 1.26 + mChildEvent(nullptr), 1.27 + mChildGuard(nullptr), 1.28 + mRegWait(nullptr), 1.29 + mFileMapping(nullptr), 1.30 + mView(nullptr), 1.31 + mIsConnected(false), 1.32 + mTimeout(INFINITE) 1.33 +{ 1.34 +} 1.35 + 1.36 +MiniShmParent::~MiniShmParent() 1.37 +{ 1.38 + CleanUp(); 1.39 +} 1.40 + 1.41 +void 1.42 +MiniShmParent::CleanUp() 1.43 +{ 1.44 + if (mRegWait) { 1.45 + ::UnregisterWaitEx(mRegWait, INVALID_HANDLE_VALUE); 1.46 + mRegWait = nullptr; 1.47 + } 1.48 + if (mParentEvent) { 1.49 + ::CloseHandle(mParentEvent); 1.50 + mParentEvent = nullptr; 1.51 + } 1.52 + if (mParentGuard) { 1.53 + ::CloseHandle(mParentGuard); 1.54 + mParentGuard = nullptr; 1.55 + } 1.56 + if (mChildEvent) { 1.57 + ::CloseHandle(mChildEvent); 1.58 + mChildEvent = nullptr; 1.59 + } 1.60 + if (mChildGuard) { 1.61 + ::CloseHandle(mChildGuard); 1.62 + mChildGuard = nullptr; 1.63 + } 1.64 + if (mView) { 1.65 + ::UnmapViewOfFile(mView); 1.66 + mView = nullptr; 1.67 + } 1.68 + if (mFileMapping) { 1.69 + ::CloseHandle(mFileMapping); 1.70 + mFileMapping = nullptr; 1.71 + } 1.72 +} 1.73 + 1.74 +nsresult 1.75 +MiniShmParent::Init(MiniShmObserver* aObserver, const DWORD aTimeout, 1.76 + const unsigned int aSectionSize) 1.77 +{ 1.78 + if (!aObserver || !aSectionSize || (aSectionSize % 0x1000) || !aTimeout) { 1.79 + return NS_ERROR_ILLEGAL_VALUE; 1.80 + } 1.81 + if (mFileMapping) { 1.82 + return NS_ERROR_ALREADY_INITIALIZED; 1.83 + } 1.84 + SECURITY_ATTRIBUTES securityAttributes = {sizeof(securityAttributes), 1.85 + nullptr, 1.86 + TRUE}; 1.87 + ScopedHandle parentEvent(::CreateEvent(&securityAttributes, 1.88 + FALSE, 1.89 + FALSE, 1.90 + nullptr)); 1.91 + if (!parentEvent.IsValid()) { 1.92 + return NS_ERROR_FAILURE; 1.93 + } 1.94 + ScopedHandle parentGuard(::CreateEvent(&securityAttributes, 1.95 + FALSE, 1.96 + TRUE, 1.97 + nullptr)); 1.98 + if (!parentGuard.IsValid()) { 1.99 + return NS_ERROR_FAILURE; 1.100 + } 1.101 + ScopedHandle childEvent(::CreateEvent(&securityAttributes, 1.102 + FALSE, 1.103 + FALSE, 1.104 + nullptr)); 1.105 + if (!childEvent.IsValid()) { 1.106 + return NS_ERROR_FAILURE; 1.107 + } 1.108 + ScopedHandle childGuard(::CreateEvent(&securityAttributes, 1.109 + FALSE, 1.110 + TRUE, 1.111 + nullptr)); 1.112 + if (!childGuard.IsValid()) { 1.113 + return NS_ERROR_FAILURE; 1.114 + } 1.115 + ScopedHandle mapping(::CreateFileMapping(INVALID_HANDLE_VALUE, 1.116 + &securityAttributes, 1.117 + PAGE_READWRITE, 1.118 + 0, 1.119 + aSectionSize, 1.120 + nullptr)); 1.121 + if (!mapping.IsValid()) { 1.122 + return NS_ERROR_FAILURE; 1.123 + } 1.124 + ScopedMappedFileView view(::MapViewOfFile(mapping, 1.125 + FILE_MAP_WRITE, 1.126 + 0, 0, 0)); 1.127 + if (!view.IsValid()) { 1.128 + return NS_ERROR_FAILURE; 1.129 + } 1.130 + nsresult rv = SetView(view, aSectionSize, false); 1.131 + NS_ENSURE_SUCCESS(rv, rv); 1.132 + rv = SetGuard(childGuard, aTimeout); 1.133 + NS_ENSURE_SUCCESS(rv, rv); 1.134 + 1.135 + MiniShmInit* initStruct = nullptr; 1.136 + rv = GetWritePtrInternal(initStruct); 1.137 + NS_ENSURE_SUCCESS(rv, rv); 1.138 + initStruct->mParentEvent = parentEvent; 1.139 + initStruct->mParentGuard = parentGuard; 1.140 + initStruct->mChildEvent = childEvent; 1.141 + initStruct->mChildGuard = childGuard; 1.142 + 1.143 + if (!::RegisterWaitForSingleObject(&mRegWait, 1.144 + parentEvent, 1.145 + &SOnEvent, 1.146 + this, 1.147 + INFINITE, 1.148 + WT_EXECUTEDEFAULT)) { 1.149 + return NS_ERROR_FAILURE; 1.150 + } 1.151 + 1.152 + mParentEvent = parentEvent.Take(); 1.153 + mParentGuard = parentGuard.Take(); 1.154 + mChildEvent = childEvent.Take(); 1.155 + mChildGuard = childGuard.Take(); 1.156 + mFileMapping = mapping.Take(); 1.157 + mView = view.Take(); 1.158 + mSectionSize = aSectionSize; 1.159 + SetObserver(aObserver); 1.160 + mTimeout = aTimeout; 1.161 + return NS_OK; 1.162 +} 1.163 + 1.164 +nsresult 1.165 +MiniShmParent::GetCookie(std::wstring& cookie) 1.166 +{ 1.167 + if (!mFileMapping) { 1.168 + return NS_ERROR_NOT_INITIALIZED; 1.169 + } 1.170 + std::wostringstream oss; 1.171 + oss << mFileMapping; 1.172 + if (!oss) { 1.173 + return NS_ERROR_FAILURE; 1.174 + } 1.175 + cookie = oss.str(); 1.176 + return NS_OK; 1.177 +} 1.178 + 1.179 +nsresult 1.180 +MiniShmParent::Send() 1.181 +{ 1.182 + if (!mChildEvent) { 1.183 + return NS_ERROR_NOT_INITIALIZED; 1.184 + } 1.185 + if (!::SetEvent(mChildEvent)) { 1.186 + return NS_ERROR_FAILURE; 1.187 + } 1.188 + return NS_OK; 1.189 +} 1.190 + 1.191 +bool 1.192 +MiniShmParent::IsConnected() const 1.193 +{ 1.194 + return mIsConnected; 1.195 +} 1.196 + 1.197 +void 1.198 +MiniShmParent::OnEvent() 1.199 +{ 1.200 + if (mIsConnected) { 1.201 + MiniShmBase::OnEvent(); 1.202 + } else { 1.203 + FinalizeConnection(); 1.204 + } 1.205 + ::SetEvent(mParentGuard); 1.206 +} 1.207 + 1.208 +void 1.209 +MiniShmParent::FinalizeConnection() 1.210 +{ 1.211 + const MiniShmInitComplete* initCompleteStruct = nullptr; 1.212 + nsresult rv = GetReadPtr(initCompleteStruct); 1.213 + mIsConnected = NS_SUCCEEDED(rv) && initCompleteStruct->mSucceeded; 1.214 + if (mIsConnected) { 1.215 + OnConnect(); 1.216 + } 1.217 +} 1.218 + 1.219 +} // namespace plugins 1.220 +} // namespace mozilla 1.221 +