tor-browser

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

Aggregation.h (3154B)


      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_Aggregation_h
      8 #define mozilla_mscom_Aggregation_h
      9 
     10 #include "mozilla/Attributes.h"
     11 
     12 #include <stddef.h>
     13 #include <unknwn.h>
     14 
     15 namespace mozilla {
     16 namespace mscom {
     17 
     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).
     25 */
     26 template <typename RefCntT>
     27 class MOZ_RAII StabilizedRefCount {
     28 public:
     29  explicit StabilizedRefCount(RefCntT& aRefCnt) : mRefCnt(aRefCnt) {
     30    ++aRefCnt;
     31  }
     32 
     33  ~StabilizedRefCount() { --mRefCnt; }
     34 
     35  StabilizedRefCount(const StabilizedRefCount&) = delete;
     36  StabilizedRefCount(StabilizedRefCount&&) = delete;
     37  StabilizedRefCount& operator=(const StabilizedRefCount&) = delete;
     38  StabilizedRefCount& operator=(StabilizedRefCount&&) = delete;
     39 
     40 private:
     41  RefCntT& mRefCnt;
     42 };
     43 
     44 namespace detail {
     45 
     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);
     51  }
     52 
     53  STDMETHODIMP_(ULONG) AddRef() override { return This()->InternalAddRef(); }
     54 
     55  STDMETHODIMP_(ULONG) Release() override { return This()->InternalRelease(); }
     56 
     57 private:
     58  T* This() {
     59    return reinterpret_cast<T*>(reinterpret_cast<char*>(this) -
     60                                offsetof(T, mInternalUnknown));
     61  }
     62 };
     63 
     64 }  // namespace detail
     65 }  // namespace mscom
     66 }  // namespace mozilla
     67 
     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(); } \
     75                                                                        \
     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
     82 
     83 #endif  // mozilla_mscom_Aggregation_h