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
{
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());
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());
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;
69 template <COINIT AptType
, bool UseOLE1
= false>
70 class MOZ_NON_TEMPORARY_CLASS ApartmentRegionT final
{
71 static COINIT
ActualType() {
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
);
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;
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