Backed out changeset f85447f6f56d (bug 1891145) for causing mochitest failures @...
[gecko.git] / ipc / mscom / ApartmentRegion.h
blobea942b95b574425f3d90210ddfa658744e564858
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/. */
7 #ifndef mozilla_mscom_ApartmentRegion_h
8 #define mozilla_mscom_ApartmentRegion_h
10 #include "mozilla/Assertions.h"
11 #include "mozilla/Attributes.h"
12 #include "mozilla/mscom/COMWrappers.h"
14 namespace mozilla::mscom {
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.
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.
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.
31 constexpr ApartmentRegion() : mInitResult(CO_E_NOTINITIALIZED) {}
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());
39 ~ApartmentRegion() {
40 if (IsValid()) {
41 wrapped::CoUninitialize();
45 explicit operator bool() const { return IsValid(); }
47 bool IsValidOutermost() const { return mInitResult == S_OK; }
49 bool IsValid() const { return SUCCEEDED(mInitResult); }
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();
58 HRESULT GetHResult() const { return mInitResult; }
60 ApartmentRegion(const ApartmentRegion&) = delete;
61 ApartmentRegion& operator=(const ApartmentRegion&) = delete;
62 ApartmentRegion(ApartmentRegion&&) = delete;
63 ApartmentRegion& operator=(ApartmentRegion&&) = delete;
65 private:
66 HRESULT mInitResult;
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);
79 public:
80 ApartmentRegionT() : mAptRgn(ActualType()) {}
82 ~ApartmentRegionT() = default;
84 explicit operator bool() const { return mAptRgn.IsValid(); }
86 bool IsValidOutermost() const { return mAptRgn.IsValidOutermost(); }
88 bool IsValid() const { return mAptRgn.IsValid(); }
90 HRESULT GetHResult() const { return mAptRgn.GetHResult(); }
92 ApartmentRegionT(const ApartmentRegionT&) = delete;
93 ApartmentRegionT& operator=(const ApartmentRegionT&) = delete;
94 ApartmentRegionT(ApartmentRegionT&&) = delete;
95 ApartmentRegionT& operator=(ApartmentRegionT&&) = delete;
97 private:
98 ApartmentRegion mAptRgn;
101 using STARegion = ApartmentRegionT<COINIT_APARTMENTTHREADED>;
102 using MTARegion = ApartmentRegionT<COINIT_MULTITHREADED>;
104 } // namespace mozilla::mscom
106 #endif // mozilla_mscom_ApartmentRegion_h