dom/plugins/ipc/hangui/MiniShmChild.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 "MiniShmChild.h"
     9 #include <limits>
    10 #include <sstream>
    12 namespace mozilla {
    13 namespace plugins {
    15 MiniShmChild::MiniShmChild()
    16   : mParentEvent(nullptr),
    17     mParentGuard(nullptr),
    18     mChildEvent(nullptr),
    19     mChildGuard(nullptr),
    20     mFileMapping(nullptr),
    21     mRegWait(nullptr),
    22     mView(nullptr),
    23     mTimeout(INFINITE)
    24 {}
    26 MiniShmChild::~MiniShmChild()
    27 {
    28   if (mRegWait) {
    29     ::UnregisterWaitEx(mRegWait, INVALID_HANDLE_VALUE);
    30   }
    31   if (mParentGuard) {
    32     // Try to avoid shutting down while the parent's event handler is running.
    33     ::WaitForSingleObject(mParentGuard, mTimeout);
    34     ::CloseHandle(mParentGuard);
    35   }
    36   if (mParentEvent) {
    37     ::CloseHandle(mParentEvent);
    38   }
    39   if (mChildEvent) {
    40     ::CloseHandle(mChildEvent);
    41   }
    42   if (mChildGuard) {
    43     ::CloseHandle(mChildGuard);
    44   }
    45   if (mView) {
    46     ::UnmapViewOfFile(mView);
    47   }
    48   if (mFileMapping) {
    49     ::CloseHandle(mFileMapping);
    50   }
    51 }
    53 nsresult
    54 MiniShmChild::Init(MiniShmObserver* aObserver, const std::wstring& aCookie,
    55                    const DWORD aTimeout)
    56 {
    57   if (aCookie.empty() || !aTimeout) {
    58     return NS_ERROR_ILLEGAL_VALUE;
    59   }
    60   if (mFileMapping) {
    61     return NS_ERROR_ALREADY_INITIALIZED;
    62   }
    63   std::wistringstream iss(aCookie);
    64   HANDLE mapHandle = nullptr;
    65   iss >> mapHandle;
    66   if (!iss) {
    67     return NS_ERROR_ILLEGAL_VALUE;
    68   }
    69   ScopedMappedFileView view(::MapViewOfFile(mapHandle,
    70                                             FILE_MAP_WRITE,
    71                                             0, 0, 0));
    72   if (!view.IsValid()) {
    73     return NS_ERROR_FAILURE;
    74   }
    75   MEMORY_BASIC_INFORMATION memInfo = {0};
    76   SIZE_T querySize = ::VirtualQuery(view, &memInfo, sizeof(memInfo));
    77   unsigned int mappingSize = 0;
    78   if (querySize) {
    79     if (memInfo.RegionSize <= std::numeric_limits<unsigned int>::max()) {
    80       mappingSize = static_cast<unsigned int>(memInfo.RegionSize);
    81     }
    82   }
    83   if (!querySize || !mappingSize) {
    84     return NS_ERROR_FAILURE;
    85   }
    86   nsresult rv = SetView(view, mappingSize, true);
    87   if (NS_FAILED(rv)) {
    88     return rv;
    89   }
    91   const MiniShmInit* initStruct = nullptr;
    92   rv = GetReadPtr(initStruct);
    93   if (NS_FAILED(rv)) {
    94     return rv;
    95   }
    96   if (!initStruct->mParentEvent || !initStruct->mParentGuard ||
    97       !initStruct->mChildEvent || !initStruct->mChildGuard) {
    98     return NS_ERROR_FAILURE;
    99   }
   100   rv = SetGuard(initStruct->mParentGuard, aTimeout);
   101   if (NS_FAILED(rv)) {
   102     return rv;
   103   }
   104   if (!::RegisterWaitForSingleObject(&mRegWait,
   105                                      initStruct->mChildEvent,
   106                                      &SOnEvent,
   107                                      this,
   108                                      INFINITE,
   109                                      WT_EXECUTEDEFAULT)) {
   110     return NS_ERROR_FAILURE;
   111   }
   113   MiniShmInitComplete* initCompleteStruct = nullptr;
   114   rv = GetWritePtrInternal(initCompleteStruct);
   115   if (NS_FAILED(rv)) {
   116     ::UnregisterWaitEx(mRegWait, INVALID_HANDLE_VALUE);
   117     mRegWait = nullptr;
   118     return NS_ERROR_FAILURE;
   119   }
   121   initCompleteStruct->mSucceeded = true;
   123   // We must set the member variables before we signal the event
   124   mFileMapping = mapHandle;
   125   mView = view.Take();
   126   mParentEvent = initStruct->mParentEvent;
   127   mParentGuard = initStruct->mParentGuard;
   128   mChildEvent = initStruct->mChildEvent;
   129   mChildGuard = initStruct->mChildGuard;
   130   SetObserver(aObserver);
   131   mTimeout = aTimeout;
   133   rv = Send();
   134   if (NS_FAILED(rv)) {
   135     initCompleteStruct->mSucceeded = false;
   136     mFileMapping = nullptr;
   137     view.Set(mView);
   138     mView = nullptr;
   139     mParentEvent = nullptr;
   140     mParentGuard = nullptr;
   141     mChildEvent = nullptr;
   142     mChildGuard = nullptr;
   143     ::UnregisterWaitEx(mRegWait, INVALID_HANDLE_VALUE);
   144     mRegWait = nullptr;
   145     return rv;
   146   }
   148   OnConnect();
   149   return NS_OK;
   150 }
   152 nsresult
   153 MiniShmChild::Send()
   154 {
   155   if (!mParentEvent) {
   156     return NS_ERROR_NOT_INITIALIZED;
   157   }
   158   if (!::SetEvent(mParentEvent)) {
   159     return NS_ERROR_FAILURE;
   160   }
   161   return NS_OK;
   162 }
   164 void
   165 MiniShmChild::OnEvent()
   166 {
   167   MiniShmBase::OnEvent();
   168   ::SetEvent(mChildGuard);
   169 }
   171 } // namespace plugins
   172 } // namespace mozilla

mercurial