Backed out changeset f85447f6f56d (bug 1891145) for causing mochitest failures @...
[gecko.git] / ipc / mscom / Aggregation.h
blobca171e39cce2e3838764917fd3363394eca9133f
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_Aggregation_h
8 #define mozilla_mscom_Aggregation_h
10 #include "mozilla/Attributes.h"
12 #include <stddef.h>
13 #include <unknwn.h>
15 namespace mozilla {
16 namespace mscom {
18 /**
19 * This is used for stabilizing a COM object's reference count during
20 * construction when that object aggregates other objects. Since the aggregated
21 * object(s) may AddRef() or Release(), we need to artifically boost the
22 * refcount to prevent premature destruction. Note that we increment/decrement
23 * instead of AddRef()/Release() in this class because we want to adjust the
24 * refcount without causing any other side effects (like object destruction).
26 template <typename RefCntT>
27 class MOZ_RAII StabilizedRefCount {
28 public:
29 explicit StabilizedRefCount(RefCntT& aRefCnt) : mRefCnt(aRefCnt) {
30 ++aRefCnt;
33 ~StabilizedRefCount() { --mRefCnt; }
35 StabilizedRefCount(const StabilizedRefCount&) = delete;
36 StabilizedRefCount(StabilizedRefCount&&) = delete;
37 StabilizedRefCount& operator=(const StabilizedRefCount&) = delete;
38 StabilizedRefCount& operator=(StabilizedRefCount&&) = delete;
40 private:
41 RefCntT& mRefCnt;
44 namespace detail {
46 template <typename T>
47 class InternalUnknown : public IUnknown {
48 public:
49 STDMETHODIMP QueryInterface(REFIID aIid, void** aOutInterface) override {
50 return This()->InternalQueryInterface(aIid, aOutInterface);
53 STDMETHODIMP_(ULONG) AddRef() override { return This()->InternalAddRef(); }
55 STDMETHODIMP_(ULONG) Release() override { return This()->InternalRelease(); }
57 private:
58 T* This() {
59 return reinterpret_cast<T*>(reinterpret_cast<char*>(this) -
60 offsetof(T, mInternalUnknown));
64 } // namespace detail
65 } // namespace mscom
66 } // namespace mozilla
68 #define DECLARE_AGGREGATABLE(Type) \
69 public: \
70 STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override { \
71 return mOuter->QueryInterface(riid, ppv); \
72 } \
73 STDMETHODIMP_(ULONG) AddRef() override { return mOuter->AddRef(); } \
74 STDMETHODIMP_(ULONG) Release() override { return mOuter->Release(); } \
76 protected: \
77 STDMETHODIMP InternalQueryInterface(REFIID riid, void** ppv); \
78 STDMETHODIMP_(ULONG) InternalAddRef(); \
79 STDMETHODIMP_(ULONG) InternalRelease(); \
80 friend class mozilla::mscom::detail::InternalUnknown<Type>; \
81 mozilla::mscom::detail::InternalUnknown<Type> mInternalUnknown
83 #endif // mozilla_mscom_Aggregation_h