mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 00:32:11 +00:00
a26d4b939e
Because Interceptors disable COM garbage collection to improve performance, they never receive Release calls from remote clients. If the object can be shut down while clients still hold a reference, this function can be used to force COM to disconnect all remote connections (using CoDisconnectObject) and thus release the associated references to the Interceptor, its target and any objects associated with the HandlerProvider. A HandlerProvider::DisconnectHandlerRemotes method also had to be added to allow HandlerProviders to disconnect clients for their own objects. MozReview-Commit-ID: JaxEkOtrP1M --HG-- extra : rebase_source : bc7a4ab79458eaaddcef8df74ff4d6f685fbfdce extra : histedit_source : 087f17f09a0c0e1c8e3b5f6d9690f331c15f0b95
92 lines
3.2 KiB
C++
92 lines
3.2 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef mozilla_mscom_MainThreadHandoff_h
|
|
#define mozilla_mscom_MainThreadHandoff_h
|
|
|
|
#include "mozilla/Assertions.h"
|
|
#include "mozilla/Move.h"
|
|
#include "mozilla/mscom/Interceptor.h"
|
|
#include "mozilla/mscom/MainThreadInvoker.h"
|
|
#include "mozilla/mscom/Utils.h"
|
|
#include "mozilla/Mutex.h"
|
|
#include "nsTArray.h"
|
|
|
|
namespace mozilla {
|
|
namespace mscom {
|
|
|
|
struct ArrayData;
|
|
|
|
class MainThreadHandoff final : public IInterceptorSink
|
|
, public ICallFrameWalker
|
|
{
|
|
public:
|
|
static HRESULT Create(IHandlerProvider* aHandlerProvider,
|
|
IInterceptorSink** aOutput);
|
|
|
|
template <typename Interface>
|
|
static HRESULT WrapInterface(STAUniquePtr<Interface> aTargetInterface,
|
|
Interface** aOutInterface)
|
|
{
|
|
return WrapInterface<Interface>(Move(aTargetInterface), nullptr,
|
|
aOutInterface);
|
|
}
|
|
|
|
template <typename Interface>
|
|
static HRESULT WrapInterface(STAUniquePtr<Interface> aTargetInterface,
|
|
IHandlerProvider* aHandlerProvider,
|
|
Interface** aOutInterface)
|
|
{
|
|
MOZ_ASSERT(!IsProxy(aTargetInterface.get()));
|
|
RefPtr<IInterceptorSink> handoff;
|
|
HRESULT hr = MainThreadHandoff::Create(aHandlerProvider,
|
|
getter_AddRefs(handoff));
|
|
if (FAILED(hr)) {
|
|
return hr;
|
|
}
|
|
return CreateInterceptor(Move(aTargetInterface), handoff, aOutInterface);
|
|
}
|
|
|
|
// IUnknown
|
|
STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override;
|
|
STDMETHODIMP_(ULONG) AddRef() override;
|
|
STDMETHODIMP_(ULONG) Release() override;
|
|
|
|
// ICallFrameEvents
|
|
STDMETHODIMP OnCall(ICallFrame* aFrame) override;
|
|
|
|
// IInterceptorSink
|
|
STDMETHODIMP SetInterceptor(IWeakReference* aInterceptor) override;
|
|
STDMETHODIMP GetHandler(NotNull<CLSID*> aHandlerClsid) override;
|
|
STDMETHODIMP GetHandlerPayloadSize(NotNull<IInterceptor*> aInterceptor,
|
|
NotNull<DWORD*> aOutPayloadSize) override;
|
|
STDMETHODIMP WriteHandlerPayload(NotNull<IInterceptor*> aInterceptor,
|
|
NotNull<IStream*> aStream) override;
|
|
STDMETHODIMP_(REFIID) MarshalAs(REFIID aIid) override;
|
|
STDMETHODIMP DisconnectHandlerRemotes() override;
|
|
|
|
// ICallFrameWalker
|
|
STDMETHODIMP OnWalkInterface(REFIID aIid, PVOID* aInterface, BOOL aIsInParam,
|
|
BOOL aIsOutParam) override;
|
|
|
|
private:
|
|
explicit MainThreadHandoff(IHandlerProvider* aHandlerProvider);
|
|
~MainThreadHandoff();
|
|
HRESULT FixArrayElements(ICallFrame* aFrame,
|
|
const ArrayData& aArrayData);
|
|
HRESULT FixIServiceProvider(ICallFrame* aFrame);
|
|
|
|
private:
|
|
ULONG mRefCnt;
|
|
RefPtr<IWeakReference> mInterceptor;
|
|
RefPtr<IHandlerProvider> mHandlerProvider;
|
|
};
|
|
|
|
} // namespace mscom
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_mscom_MainThreadHandoff_h
|