Bug 322754 Pref service asserts instead of removing dead references r+sr=darin

This commit is contained in:
neil%parkwaycc.co.uk 2006-01-10 12:20:17 +00:00
parent c44b992ba0
commit 180a841df6

View File

@ -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);
}
}