Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "MiniShmParent.h"
9 #include "base/scoped_handle.h"
11 #include <sstream>
13 namespace mozilla {
14 namespace plugins {
16 // static
17 const unsigned int MiniShmParent::kDefaultMiniShmSectionSize = 0x1000;
19 MiniShmParent::MiniShmParent()
20 : mSectionSize(0),
21 mParentEvent(nullptr),
22 mParentGuard(nullptr),
23 mChildEvent(nullptr),
24 mChildGuard(nullptr),
25 mRegWait(nullptr),
26 mFileMapping(nullptr),
27 mView(nullptr),
28 mIsConnected(false),
29 mTimeout(INFINITE)
30 {
31 }
33 MiniShmParent::~MiniShmParent()
34 {
35 CleanUp();
36 }
38 void
39 MiniShmParent::CleanUp()
40 {
41 if (mRegWait) {
42 ::UnregisterWaitEx(mRegWait, INVALID_HANDLE_VALUE);
43 mRegWait = nullptr;
44 }
45 if (mParentEvent) {
46 ::CloseHandle(mParentEvent);
47 mParentEvent = nullptr;
48 }
49 if (mParentGuard) {
50 ::CloseHandle(mParentGuard);
51 mParentGuard = nullptr;
52 }
53 if (mChildEvent) {
54 ::CloseHandle(mChildEvent);
55 mChildEvent = nullptr;
56 }
57 if (mChildGuard) {
58 ::CloseHandle(mChildGuard);
59 mChildGuard = nullptr;
60 }
61 if (mView) {
62 ::UnmapViewOfFile(mView);
63 mView = nullptr;
64 }
65 if (mFileMapping) {
66 ::CloseHandle(mFileMapping);
67 mFileMapping = nullptr;
68 }
69 }
71 nsresult
72 MiniShmParent::Init(MiniShmObserver* aObserver, const DWORD aTimeout,
73 const unsigned int aSectionSize)
74 {
75 if (!aObserver || !aSectionSize || (aSectionSize % 0x1000) || !aTimeout) {
76 return NS_ERROR_ILLEGAL_VALUE;
77 }
78 if (mFileMapping) {
79 return NS_ERROR_ALREADY_INITIALIZED;
80 }
81 SECURITY_ATTRIBUTES securityAttributes = {sizeof(securityAttributes),
82 nullptr,
83 TRUE};
84 ScopedHandle parentEvent(::CreateEvent(&securityAttributes,
85 FALSE,
86 FALSE,
87 nullptr));
88 if (!parentEvent.IsValid()) {
89 return NS_ERROR_FAILURE;
90 }
91 ScopedHandle parentGuard(::CreateEvent(&securityAttributes,
92 FALSE,
93 TRUE,
94 nullptr));
95 if (!parentGuard.IsValid()) {
96 return NS_ERROR_FAILURE;
97 }
98 ScopedHandle childEvent(::CreateEvent(&securityAttributes,
99 FALSE,
100 FALSE,
101 nullptr));
102 if (!childEvent.IsValid()) {
103 return NS_ERROR_FAILURE;
104 }
105 ScopedHandle childGuard(::CreateEvent(&securityAttributes,
106 FALSE,
107 TRUE,
108 nullptr));
109 if (!childGuard.IsValid()) {
110 return NS_ERROR_FAILURE;
111 }
112 ScopedHandle mapping(::CreateFileMapping(INVALID_HANDLE_VALUE,
113 &securityAttributes,
114 PAGE_READWRITE,
115 0,
116 aSectionSize,
117 nullptr));
118 if (!mapping.IsValid()) {
119 return NS_ERROR_FAILURE;
120 }
121 ScopedMappedFileView view(::MapViewOfFile(mapping,
122 FILE_MAP_WRITE,
123 0, 0, 0));
124 if (!view.IsValid()) {
125 return NS_ERROR_FAILURE;
126 }
127 nsresult rv = SetView(view, aSectionSize, false);
128 NS_ENSURE_SUCCESS(rv, rv);
129 rv = SetGuard(childGuard, aTimeout);
130 NS_ENSURE_SUCCESS(rv, rv);
132 MiniShmInit* initStruct = nullptr;
133 rv = GetWritePtrInternal(initStruct);
134 NS_ENSURE_SUCCESS(rv, rv);
135 initStruct->mParentEvent = parentEvent;
136 initStruct->mParentGuard = parentGuard;
137 initStruct->mChildEvent = childEvent;
138 initStruct->mChildGuard = childGuard;
140 if (!::RegisterWaitForSingleObject(&mRegWait,
141 parentEvent,
142 &SOnEvent,
143 this,
144 INFINITE,
145 WT_EXECUTEDEFAULT)) {
146 return NS_ERROR_FAILURE;
147 }
149 mParentEvent = parentEvent.Take();
150 mParentGuard = parentGuard.Take();
151 mChildEvent = childEvent.Take();
152 mChildGuard = childGuard.Take();
153 mFileMapping = mapping.Take();
154 mView = view.Take();
155 mSectionSize = aSectionSize;
156 SetObserver(aObserver);
157 mTimeout = aTimeout;
158 return NS_OK;
159 }
161 nsresult
162 MiniShmParent::GetCookie(std::wstring& cookie)
163 {
164 if (!mFileMapping) {
165 return NS_ERROR_NOT_INITIALIZED;
166 }
167 std::wostringstream oss;
168 oss << mFileMapping;
169 if (!oss) {
170 return NS_ERROR_FAILURE;
171 }
172 cookie = oss.str();
173 return NS_OK;
174 }
176 nsresult
177 MiniShmParent::Send()
178 {
179 if (!mChildEvent) {
180 return NS_ERROR_NOT_INITIALIZED;
181 }
182 if (!::SetEvent(mChildEvent)) {
183 return NS_ERROR_FAILURE;
184 }
185 return NS_OK;
186 }
188 bool
189 MiniShmParent::IsConnected() const
190 {
191 return mIsConnected;
192 }
194 void
195 MiniShmParent::OnEvent()
196 {
197 if (mIsConnected) {
198 MiniShmBase::OnEvent();
199 } else {
200 FinalizeConnection();
201 }
202 ::SetEvent(mParentGuard);
203 }
205 void
206 MiniShmParent::FinalizeConnection()
207 {
208 const MiniShmInitComplete* initCompleteStruct = nullptr;
209 nsresult rv = GetReadPtr(initCompleteStruct);
210 mIsConnected = NS_SUCCEEDED(rv) && initCompleteStruct->mSucceeded;
211 if (mIsConnected) {
212 OnConnect();
213 }
214 }
216 } // namespace plugins
217 } // namespace mozilla