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"
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
{
29 explicit StabilizedRefCount(RefCntT
& aRefCnt
) : mRefCnt(aRefCnt
) {
33 ~StabilizedRefCount() { --mRefCnt
; }
35 StabilizedRefCount(const StabilizedRefCount
&) = delete;
36 StabilizedRefCount(StabilizedRefCount
&&) = delete;
37 StabilizedRefCount
& operator=(const StabilizedRefCount
&) = delete;
38 StabilizedRefCount
& operator=(StabilizedRefCount
&&) = delete;
47 class InternalUnknown
: public IUnknown
{
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(); }
59 return reinterpret_cast<T
*>(reinterpret_cast<char*>(this) -
60 offsetof(T
, mInternalUnknown
));
66 } // namespace mozilla
68 #define DECLARE_AGGREGATABLE(Type) \
70 STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override { \
71 return mOuter->QueryInterface(riid, ppv); \
73 STDMETHODIMP_(ULONG) AddRef() override { return mOuter->AddRef(); } \
74 STDMETHODIMP_(ULONG) Release() override { return mOuter->Release(); } \
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