mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-10 01:08:21 +00:00
Bug 322754 Pref service asserts instead of removing dead references r+sr=darin
This commit is contained in:
parent
c44b992ba0
commit
180a841df6
@ -68,9 +68,9 @@ struct EnumerateData {
|
||||
};
|
||||
|
||||
struct PrefCallbackData {
|
||||
nsIPrefBranch *pBranch;
|
||||
nsISupports *pObserver;
|
||||
PRBool bIsWeakRef;
|
||||
nsPrefBranch *pBranch;
|
||||
nsIObserver *pObserver;
|
||||
nsIWeakReference *pWeakRef;
|
||||
};
|
||||
|
||||
|
||||
@ -634,11 +634,10 @@ NS_IMETHODIMP nsPrefBranch::AddObserver(const char *aDomain, nsIObserver *aObser
|
||||
if (nsnull == pCallback)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
pCallback->pBranch = NS_STATIC_CAST(nsIPrefBranch *, this);
|
||||
pCallback->bIsWeakRef = aHoldWeak;
|
||||
pCallback->pBranch = this;
|
||||
pCallback->pObserver = aObserver;
|
||||
|
||||
// hold a weak reference to the observer if so requested
|
||||
nsCOMPtr<nsISupports> observerRef;
|
||||
if (aHoldWeak) {
|
||||
nsCOMPtr<nsISupportsWeakReference> weakRefFactory = do_QueryInterface(aObserver);
|
||||
if (!weakRefFactory) {
|
||||
@ -647,12 +646,11 @@ NS_IMETHODIMP nsPrefBranch::AddObserver(const char *aDomain, nsIObserver *aObser
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
nsCOMPtr<nsIWeakReference> tmp = do_GetWeakReference(weakRefFactory);
|
||||
observerRef = tmp;
|
||||
NS_ADDREF(pCallback->pWeakRef = tmp);
|
||||
} else {
|
||||
observerRef = aObserver;
|
||||
pCallback->pWeakRef = nsnull;
|
||||
NS_ADDREF(pCallback->pObserver);
|
||||
}
|
||||
pCallback->pObserver = observerRef;
|
||||
NS_ADDREF(pCallback->pObserver);
|
||||
|
||||
mObservers->AppendElement(pCallback);
|
||||
mObserverDomains.AppendCString(nsCString(aDomain));
|
||||
@ -686,18 +684,7 @@ NS_IMETHODIMP nsPrefBranch::RemoveObserver(const char *aDomain, nsIObserver *aOb
|
||||
for (i = 0; i < count; i++) {
|
||||
pCallback = (PrefCallbackData *)mObservers->ElementAt(i);
|
||||
if (pCallback) {
|
||||
nsCOMPtr<nsISupports> observerRef;
|
||||
if (pCallback->bIsWeakRef) {
|
||||
nsCOMPtr<nsISupportsWeakReference> weakRefFactory = do_QueryInterface(aObserver);
|
||||
if (weakRefFactory) {
|
||||
nsCOMPtr<nsIWeakReference> tmp = do_GetWeakReference(aObserver);
|
||||
observerRef = tmp;
|
||||
}
|
||||
}
|
||||
if (!observerRef)
|
||||
observerRef = aObserver;
|
||||
|
||||
if (pCallback->pObserver == observerRef) {
|
||||
if (pCallback->pObserver == aObserver) {
|
||||
mObserverDomains.CStringAt(i, domain);
|
||||
if (domain.Equals(aDomain)) {
|
||||
// We must pass a fully qualified preference name to remove the callback
|
||||
@ -708,7 +695,11 @@ NS_IMETHODIMP nsPrefBranch::RemoveObserver(const char *aDomain, nsIObserver *aOb
|
||||
// what we're trying to remove ourselves right now.
|
||||
mObservers->RemoveElementAt(i);
|
||||
mObserverDomains.RemoveCStringAt(i);
|
||||
NS_RELEASE(pCallback->pObserver);
|
||||
if (pCallback->pWeakRef) {
|
||||
NS_RELEASE(pCallback->pWeakRef);
|
||||
} else {
|
||||
NS_RELEASE(pCallback->pObserver);
|
||||
}
|
||||
nsMemory::Free(pCallback);
|
||||
}
|
||||
return rv;
|
||||
@ -732,31 +723,27 @@ NS_IMETHODIMP nsPrefBranch::Observe(nsISupports *aSubject, const char *aTopic, c
|
||||
PR_STATIC_CALLBACK(nsresult) NotifyObserver(const char *newpref, void *data)
|
||||
{
|
||||
PrefCallbackData *pData = (PrefCallbackData *)data;
|
||||
nsPrefBranch *prefBranch = NS_STATIC_CAST(nsPrefBranch *, pData->pBranch);
|
||||
|
||||
// remove any root this string may contain so as to not confuse the observer
|
||||
// by passing them something other than what they passed us as a topic
|
||||
PRUint32 len = prefBranch->GetRootLength();
|
||||
PRUint32 len = pData->pBranch->GetRootLength();
|
||||
nsCAutoString suffix(newpref + len);
|
||||
|
||||
nsCOMPtr<nsIObserver> observer;
|
||||
if (pData->bIsWeakRef) {
|
||||
nsIWeakReference *weakRef = NS_STATIC_CAST(nsIWeakReference *, pData->pObserver);
|
||||
observer = do_QueryReferent(weakRef);
|
||||
if (pData->pWeakRef) {
|
||||
observer = do_QueryReferent(pData->pWeakRef);
|
||||
if (!observer) {
|
||||
// this weak referenced observer went away, remove them from the list
|
||||
nsCOMPtr<nsIPrefBranch2> pbi = do_QueryInterface(pData->pBranch);
|
||||
if (pbi) {
|
||||
observer = NS_STATIC_CAST(nsIObserver *, pData->pObserver);
|
||||
pbi->RemoveObserver(newpref, observer);
|
||||
}
|
||||
pData->pBranch->RemoveObserver(newpref, pData->pObserver);
|
||||
return NS_OK;
|
||||
}
|
||||
} else
|
||||
observer = NS_STATIC_CAST(nsIObserver *, pData->pObserver);
|
||||
} else {
|
||||
observer = pData->pObserver;
|
||||
}
|
||||
|
||||
observer->Observe(pData->pBranch, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID,
|
||||
NS_ConvertASCIItoUCS2(suffix).get());
|
||||
observer->Observe(NS_STATIC_CAST(nsIPrefBranch *, pData->pBranch),
|
||||
NS_PREFBRANCH_PREFCHANGE_TOPIC_ID,
|
||||
NS_ConvertASCIItoUTF16(suffix).get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -784,7 +771,11 @@ void nsPrefBranch::freeObserverList(void)
|
||||
// what we're trying to remove right now.
|
||||
mObservers->ReplaceElementAt(nsnull, i);
|
||||
PREF_UnregisterCallback(pref, NotifyObserver, pCallback);
|
||||
NS_RELEASE(pCallback->pObserver);
|
||||
if (pCallback->pWeakRef) {
|
||||
NS_RELEASE(pCallback->pWeakRef);
|
||||
} else {
|
||||
NS_RELEASE(pCallback->pObserver);
|
||||
}
|
||||
nsMemory::Free(pCallback);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user