michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsInterfaceRequestorAgg.h" michael@0: #include "nsIInterfaceRequestor.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "mozilla/Attributes.h" michael@0: #include "nsThreadUtils.h" michael@0: #include "nsProxyRelease.h" michael@0: michael@0: class nsInterfaceRequestorAgg MOZ_FINAL : public nsIInterfaceRequestor michael@0: { michael@0: public: michael@0: // XXX This needs to support threadsafe refcounting until we fix bug 243591. michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: NS_DECL_NSIINTERFACEREQUESTOR michael@0: michael@0: nsInterfaceRequestorAgg(nsIInterfaceRequestor *aFirst, michael@0: nsIInterfaceRequestor *aSecond, michael@0: nsIEventTarget *aConsumerTarget = nullptr) michael@0: : mFirst(aFirst) michael@0: , mSecond(aSecond) michael@0: , mConsumerTarget(aConsumerTarget) michael@0: { michael@0: if (!mConsumerTarget) { michael@0: mConsumerTarget = NS_GetCurrentThread(); michael@0: } michael@0: } michael@0: ~nsInterfaceRequestorAgg(); michael@0: michael@0: private: michael@0: nsCOMPtr mFirst, mSecond; michael@0: nsCOMPtr mConsumerTarget; michael@0: }; michael@0: michael@0: NS_IMPL_ISUPPORTS(nsInterfaceRequestorAgg, nsIInterfaceRequestor) michael@0: michael@0: NS_IMETHODIMP michael@0: nsInterfaceRequestorAgg::GetInterface(const nsIID &aIID, void **aResult) michael@0: { michael@0: nsresult rv = NS_ERROR_NO_INTERFACE; michael@0: if (mFirst) michael@0: rv = mFirst->GetInterface(aIID, aResult); michael@0: if (mSecond && NS_FAILED(rv)) michael@0: rv = mSecond->GetInterface(aIID, aResult); michael@0: return rv; michael@0: } michael@0: michael@0: nsInterfaceRequestorAgg::~nsInterfaceRequestorAgg() michael@0: { michael@0: nsIInterfaceRequestor* iir = nullptr; michael@0: mFirst.swap(iir); michael@0: if (iir) { michael@0: NS_ProxyRelease(mConsumerTarget, iir); michael@0: } michael@0: iir = nullptr; michael@0: mSecond.swap(iir); michael@0: if (iir) { michael@0: NS_ProxyRelease(mConsumerTarget, iir); michael@0: } michael@0: } michael@0: michael@0: nsresult michael@0: NS_NewInterfaceRequestorAggregation(nsIInterfaceRequestor *aFirst, michael@0: nsIInterfaceRequestor *aSecond, michael@0: nsIInterfaceRequestor **aResult) michael@0: { michael@0: *aResult = new nsInterfaceRequestorAgg(aFirst, aSecond); michael@0: if (!*aResult) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: NS_ADDREF(*aResult); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: NS_NewInterfaceRequestorAggregation(nsIInterfaceRequestor *aFirst, michael@0: nsIInterfaceRequestor *aSecond, michael@0: nsIEventTarget* aTarget, michael@0: nsIInterfaceRequestor **aResult) michael@0: { michael@0: *aResult = new nsInterfaceRequestorAgg(aFirst, aSecond, aTarget); michael@0: if (!*aResult) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: NS_ADDREF(*aResult); michael@0: return NS_OK; michael@0: }