зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1626802 part 1: mscom: Provide a way for Interceptors to avoid unnecessary cross-thread QueryInterface calls. r=aklotz
When marshaling a11y calls from the content process, there are quite a lot of cross-thread QueryInterface calls (ipc::mscom::Interceptor::QueryInterfaceTarget). Some of these are for special COM interfaces like IAgileObject and IFastRundown, which we could just special case in Interceptor::QueryInterface like we do for INoMarshal. However, it seems there are a lot of other interfaces being queried and it's not clear why. This patch adds a new HandlerProvider method: IsInterfaceMaybeSupported. This allows implementations to indicate when there are interfaces which they definitely don't support, allowing the call to be answered without a cross-thread call. Differential Revision: https://phabricator.services.mozilla.com/D69285 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
71bcb7f89c
Коммит
132a49a8a1
|
@ -25,6 +25,16 @@ struct HandlerProvider {
|
|||
NotNull<IStream*> aStream) = 0;
|
||||
virtual STDMETHODIMP_(REFIID) MarshalAs(REFIID aIid) = 0;
|
||||
virtual STDMETHODIMP DisconnectHandlerRemotes() = 0;
|
||||
|
||||
/**
|
||||
* Determine whether this interface might be supported by objects using
|
||||
* this HandlerProvider.
|
||||
* This is used to avoid unnecessary cross-thread QueryInterface calls for
|
||||
* interfaces known to be unsupported.
|
||||
* Return S_OK if the interface might be supported, E_NOINTERFACE if it
|
||||
* definitely isn't supported.
|
||||
*/
|
||||
virtual STDMETHODIMP IsInterfaceMaybeSupported(REFIID aIid) { return S_OK; }
|
||||
};
|
||||
|
||||
struct IHandlerProvider : public IUnknown, public HandlerProvider {
|
||||
|
|
|
@ -707,6 +707,10 @@ Interceptor::QueryInterfaceTarget(REFIID aIid, void** aOutput,
|
|||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
if (mEventSink->IsInterfaceMaybeSupported(aIid) == E_NOINTERFACE) {
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
MainThreadInvoker invoker;
|
||||
HRESULT hr;
|
||||
auto runOnMainThread = [&]() -> void {
|
||||
|
|
|
@ -550,6 +550,14 @@ MainThreadHandoff::DisconnectHandlerRemotes() {
|
|||
return mHandlerProvider->DisconnectHandlerRemotes();
|
||||
}
|
||||
|
||||
HRESULT
|
||||
MainThreadHandoff::IsInterfaceMaybeSupported(REFIID aIid) {
|
||||
if (!mHandlerProvider) {
|
||||
return S_OK;
|
||||
}
|
||||
return mHandlerProvider->IsInterfaceMaybeSupported(aIid);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
MainThreadHandoff::OnWalkInterface(REFIID aIid, PVOID* aInterface,
|
||||
BOOL aIsInParam, BOOL aIsOutParam) {
|
||||
|
|
|
@ -66,6 +66,7 @@ class MainThreadHandoff final : public IInterceptorSink,
|
|||
NotNull<IStream*> aStream) override;
|
||||
STDMETHODIMP_(REFIID) MarshalAs(REFIID aIid) override;
|
||||
STDMETHODIMP DisconnectHandlerRemotes() override;
|
||||
STDMETHODIMP IsInterfaceMaybeSupported(REFIID aIid) override;
|
||||
|
||||
// ICallFrameWalker
|
||||
STDMETHODIMP OnWalkInterface(REFIID aIid, PVOID* aInterface, BOOL aIsInParam,
|
||||
|
|
Загрузка…
Ссылка в новой задаче