dom/plugins/ipc/MiniShmParent.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

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

mercurial