Bug 1502284 - Extend nsMaybeWeakPtr and make expose it to the rest of the code r=erahm

This adds a way to detect if an instance is holding a weak reference or a
strong one, makes non-critical failures less chatty and adds separate methods
for adding unique and non-unique instances to an array.

Differential Revision: https://phabricator.services.mozilla.com/D11645

--HG--
rename : toolkit/components/places/nsMaybeWeakPtr.h => xpcom/base/nsMaybeWeakPtr.h
extra : moz-landing-system : lando
This commit is contained in:
Gabriele Svelto 2018-11-16 09:39:36 +00:00
parent a18175c429
commit 86d8798959
7 changed files with 51 additions and 22 deletions

View File

@ -1955,7 +1955,7 @@ nsNavBookmarks::AddObserver(nsINavBookmarkObserver* aObserver,
if (NS_WARN_IF(!mCanNotify))
return NS_ERROR_UNEXPECTED;
return mObservers.AppendWeakElement(aObserver, aOwnsWeak);
return mObservers.AppendWeakElementUnlessExists(aObserver, aOwnsWeak);
}

View File

@ -11,7 +11,6 @@
#include "nsToolkitCompsCID.h"
#include "nsCategoryCache.h"
#include "nsTHashtable.h"
#include "nsWeakReference.h"
#include "mozilla/Attributes.h"
#include "prtime.h"

View File

@ -2148,7 +2148,7 @@ nsNavHistory::AddObserver(nsINavHistoryObserver* aObserver, bool aOwnsWeak)
if (NS_WARN_IF(!mCanNotify))
return NS_ERROR_UNEXPECTED;
return mObservers.AppendWeakElement(aObserver, aOwnsWeak);
return mObservers.AppendWeakElementUnlessExists(aObserver, aOwnsWeak);
}
NS_IMETHODIMP

View File

@ -4179,7 +4179,7 @@ nsNavHistoryResult::AddObserver(nsINavHistoryResultObserver* aObserver,
bool aOwnsWeak)
{
NS_ENSURE_ARG(aObserver);
nsresult rv = mObservers.AppendWeakElement(aObserver, aOwnsWeak);
nsresult rv = mObservers.AppendWeakElementUnlessExists(aObserver, aOwnsWeak);
NS_ENSURE_SUCCESS(rv, rv);
rv = aObserver->SetResult(this);

View File

@ -14,6 +14,7 @@
#include "INativePlacesEventCallback.h"
#include "nsTArray.h"
#include "nsMaybeWeakPtr.h"
#include "nsInterfaceHashtable.h"
#include "nsDataHashtable.h"
#include "nsCycleCollectionParticipant.h"

View File

@ -80,6 +80,7 @@ EXPORTS += [
'nsISupportsImpl.h',
'nsISupportsUtils.h',
'nsIWeakReferenceUtils.h',
'nsMaybeWeakPtr.h',
'nsMemory.h',
'nsObjCExceptions.h',
'nsQueryObject.h',

View File

@ -20,16 +20,20 @@ class nsMaybeWeakPtr
{
public:
nsMaybeWeakPtr() = default;
MOZ_IMPLICIT nsMaybeWeakPtr(T* aRef) : mPtr(aRef) {}
MOZ_IMPLICIT nsMaybeWeakPtr(const nsCOMPtr<nsIWeakReference>& aRef) : mPtr(aRef) {}
MOZ_IMPLICIT nsMaybeWeakPtr(T* aRef) : mPtr(aRef), mWeak(false) {}
MOZ_IMPLICIT nsMaybeWeakPtr(const nsCOMPtr<nsIWeakReference>& aRef)
: mPtr(aRef)
, mWeak(true) {}
nsMaybeWeakPtr<T>& operator=(T* aRef) {
mPtr = aRef;
mWeak = false;
return *this;
}
nsMaybeWeakPtr<T>& operator=(const nsCOMPtr<nsIWeakReference>& aRef) {
mPtr = aRef;
mWeak = true;
return *this;
}
@ -38,11 +42,13 @@ public:
}
nsISupports* GetRawValue() const { return mPtr.get(); }
bool IsWeak() const { return mWeak; }
const nsCOMPtr<T> GetValue() const;
private:
nsCOMPtr<nsISupports> mPtr;
bool mWeak;
};
// nsMaybeWeakPtrArray is an array of MaybeWeakPtr objects, that knows how to
@ -54,23 +60,39 @@ class nsMaybeWeakPtrArray : public nsTArray<nsMaybeWeakPtr<T>>
{
typedef nsTArray<nsMaybeWeakPtr<T>> MaybeWeakArray;
nsresult SetMaybeWeakPtr(nsMaybeWeakPtr<T>& aRef, T* aElement, bool aOwnsWeak)
{
nsresult rv = NS_OK;
if (aOwnsWeak) {
aRef = do_GetWeakReference(aElement, &rv);
} else {
aRef = aElement;
}
return rv;
}
public:
nsresult AppendWeakElement(T* aElement, bool aOwnsWeak)
{
nsMaybeWeakPtr<T> ref;
MOZ_TRY(SetMaybeWeakPtr(ref, aElement, aOwnsWeak));
if (aOwnsWeak) {
ref = do_GetWeakReference(aElement);
} else {
ref = aElement;
}
MaybeWeakArray::AppendElement(ref);
return NS_OK;
}
nsresult AppendWeakElementUnlessExists(T* aElement, bool aOwnsWeak)
{
nsMaybeWeakPtr<T> ref;
MOZ_TRY(SetMaybeWeakPtr(ref, aElement, aOwnsWeak));
if (MaybeWeakArray::Contains(ref)) {
return NS_ERROR_INVALID_ARG;
}
if (!MaybeWeakArray::AppendElement(ref)) {
return NS_ERROR_OUT_OF_MEMORY;
}
MaybeWeakArray::AppendElement(ref);
return NS_OK;
}
@ -83,7 +105,9 @@ public:
// Don't use do_GetWeakReference; it should only be called if we know
// the object supports weak references.
nsCOMPtr<nsISupportsWeakReference> supWeakRef = do_QueryInterface(aElement);
NS_ENSURE_TRUE(supWeakRef, NS_ERROR_INVALID_ARG);
if (!supWeakRef) {
return NS_ERROR_INVALID_ARG;
}
nsCOMPtr<nsIWeakReference> weakRef;
nsresult rv = supWeakRef->GetWeakReference(getter_AddRefs(weakRef));
@ -105,15 +129,19 @@ nsMaybeWeakPtr<T>::GetValue() const
return nullptr;
}
nsCOMPtr<T> ref;
nsresult rv;
nsCOMPtr<T> ref = do_QueryInterface(mPtr, &rv);
if (NS_SUCCEEDED(rv)) {
return ref;
}
nsCOMPtr<nsIWeakReference> weakRef = do_QueryInterface(mPtr);
if (weakRef) {
ref = do_QueryReferent(weakRef, &rv);
if (mWeak) {
nsCOMPtr<nsIWeakReference> weakRef = do_QueryInterface(mPtr);
if (weakRef) {
ref = do_QueryReferent(weakRef, &rv);
if (NS_SUCCEEDED(rv)) {
return ref;
}
}
} else {
ref = do_QueryInterface(mPtr, &rv);
if (NS_SUCCEEDED(rv)) {
return ref;
}