tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ApartmentRegion.h (3510B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=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/. */
      6 
      7 #ifndef mozilla_mscom_ApartmentRegion_h
      8 #define mozilla_mscom_ApartmentRegion_h
      9 
     10 #include "mozilla/Assertions.h"
     11 #include "mozilla/Attributes.h"
     12 #include "mozilla/mscom/COMWrappers.h"
     13 
     14 namespace mozilla::mscom {
     15 
     16 // This runtime-dynamic apartment class is used in ProcessRuntime.cpp, to
     17 // initialize the process's main thread. Do not use it in new contexts if at all
     18 // possible; instead, prefer ApartmentRegionT, below.
     19 //
     20 // For backwards compatibility, this class does not yet automatically disable
     21 // OLE1/DDE, although there is believed to be no code relying on it.
     22 //
     23 // (TODO: phase out all uses of CoInitialize without `COINIT_DISABLE_OLE1DDE`?)
     24 class MOZ_NON_TEMPORARY_CLASS ApartmentRegion final {
     25 public:
     26  /**
     27   * This constructor is to be used when we want to instantiate the object but
     28   * we do not yet know which type of apartment we want. Call Init() to
     29   * complete initialization.
     30   */
     31  constexpr ApartmentRegion() : mInitResult(CO_E_NOTINITIALIZED) {}
     32 
     33  explicit ApartmentRegion(COINIT aAptType)
     34      : mInitResult(wrapped::CoInitializeEx(nullptr, aAptType)) {
     35    // If this fires then we're probably mixing apartments on the same thread
     36    MOZ_ASSERT(IsValid());
     37  }
     38 
     39  ~ApartmentRegion() {
     40    if (IsValid()) {
     41      wrapped::CoUninitialize();
     42    }
     43  }
     44 
     45  explicit operator bool() const { return IsValid(); }
     46 
     47  bool IsValidOutermost() const { return mInitResult == S_OK; }
     48 
     49  bool IsValid() const { return SUCCEEDED(mInitResult); }
     50 
     51  bool Init(COINIT aAptType) {
     52    MOZ_ASSERT(mInitResult == CO_E_NOTINITIALIZED);
     53    mInitResult = wrapped::CoInitializeEx(nullptr, aAptType);
     54    MOZ_ASSERT(IsValid());
     55    return IsValid();
     56  }
     57 
     58  HRESULT GetHResult() const { return mInitResult; }
     59 
     60  ApartmentRegion(const ApartmentRegion&) = delete;
     61  ApartmentRegion& operator=(const ApartmentRegion&) = delete;
     62  ApartmentRegion(ApartmentRegion&&) = delete;
     63  ApartmentRegion& operator=(ApartmentRegion&&) = delete;
     64 
     65 private:
     66  HRESULT mInitResult;
     67 };
     68 
     69 template <COINIT AptType, bool UseOLE1 = false>
     70 class MOZ_NON_TEMPORARY_CLASS ApartmentRegionT final {
     71  static COINIT ActualType() {
     72    static_assert(
     73        !((AptType & COINIT_DISABLE_OLE1DDE) == 0 && UseOLE1),
     74        "only one of `UseOLE1` and `COINIT_DISABLE_OLE1DDE` permitted");
     75    if (UseOLE1) return AptType;
     76    return static_cast<COINIT>(AptType | COINIT_DISABLE_OLE1DDE);
     77  }
     78 
     79 public:
     80  ApartmentRegionT() : mAptRgn(ActualType()) {}
     81 
     82  ~ApartmentRegionT() = default;
     83 
     84  explicit operator bool() const { return mAptRgn.IsValid(); }
     85 
     86  bool IsValidOutermost() const { return mAptRgn.IsValidOutermost(); }
     87 
     88  bool IsValid() const { return mAptRgn.IsValid(); }
     89 
     90  HRESULT GetHResult() const { return mAptRgn.GetHResult(); }
     91 
     92  ApartmentRegionT(const ApartmentRegionT&) = delete;
     93  ApartmentRegionT& operator=(const ApartmentRegionT&) = delete;
     94  ApartmentRegionT(ApartmentRegionT&&) = delete;
     95  ApartmentRegionT& operator=(ApartmentRegionT&&) = delete;
     96 
     97 private:
     98  ApartmentRegion mAptRgn;
     99 };
    100 
    101 using STARegion = ApartmentRegionT<COINIT_APARTMENTTHREADED>;
    102 using MTARegion = ApartmentRegionT<COINIT_MULTITHREADED>;
    103 
    104 }  // namespace mozilla::mscom
    105 
    106 #endif  // mozilla_mscom_ApartmentRegion_h