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_FastMarshaler_h
8 #define mozilla_mscom_FastMarshaler_h
9 
10 #include "mozilla/Atomics.h"
11 #include "mozilla/mscom/Aggregation.h"
12 #include "mozilla/RefPtr.h"
13 
14 #include <objidl.h>
15 
16 namespace mozilla {
17 namespace mscom {
18 
19 /**
20  * COM ping functionality is enabled by default and is designed to free strong
21  * references held by defunct client processes. However, this incurs a
22  * significant performance penalty in a11y code due to large numbers of remote
23  * objects being created and destroyed within a short period of time. Thus, we
24  * turn off pings to improve performance.
25  * ACHTUNG! When COM pings are disabled, Release calls from remote clients are
26  * never sent to the server! If you use this marshaler, you *must* explicitly
27  * disconnect clients using CoDisconnectObject when the object is no longer
28  * relevant. Otherwise, references to the object will never be released, causing
29  * a leak.
30  */
31 class FastMarshaler final : public IMarshal {
32  public:
33   static HRESULT Create(IUnknown* aOuter, IUnknown** aOutMarshalerUnk);
34 
35   // IMarshal
36   STDMETHODIMP GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext,
37                                  void* pvDestContext, DWORD mshlflags,
38                                  CLSID* pCid) override;
39   STDMETHODIMP GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext,
40                                  void* pvDestContext, DWORD mshlflags,
41                                  DWORD* pSize) override;
42   STDMETHODIMP MarshalInterface(IStream* pStm, REFIID riid, void* pv,
43                                 DWORD dwDestContext, void* pvDestContext,
44                                 DWORD mshlflags) override;
45   STDMETHODIMP UnmarshalInterface(IStream* pStm, REFIID riid,
46                                   void** ppv) override;
47   STDMETHODIMP ReleaseMarshalData(IStream* pStm) override;
48   STDMETHODIMP DisconnectObject(DWORD dwReserved) override;
49 
50  private:
51   FastMarshaler(IUnknown* aOuter, HRESULT* aResult);
52   ~FastMarshaler() = default;
53 
54   static DWORD GetMarshalFlags(DWORD aDestContext, DWORD aMshlFlags);
55 
56   Atomic<ULONG> mRefCnt;
57   IUnknown* mOuter;
58   RefPtr<IUnknown> mStdMarshalUnk;
59   IMarshal* mStdMarshalWeak;
60   DECLARE_AGGREGATABLE(FastMarshaler);
61 };
62 
63 }  // namespace mscom
64 }  // namespace mozilla
65 
66 #endif  // mozilla_mscom_FastMarshaler_h
67