Bug 183069 - trunk topcrash when quitting [@ nsPrefBranch::RemoveObserver].

Release our observer references only _after_ we remove them from our observer list, to avoid someone else trying to remove the same observer we're working on removing.
r=timeless sr=jst
a=jst, and #mozilla (smontagu,timeless) who acting as sheriff asked me to land this into a closed tree.
This commit is contained in:
caillon%returnzero.com 2002-12-04 08:56:34 +00:00
Родитель 6958f9c9e3
Коммит 90ab64d798
1 изменённых файлов: 9 добавлений и 5 удалений

Просмотреть файл

@ -735,10 +735,12 @@ NS_IMETHODIMP nsPrefBranch::RemoveObserver(const char *aDomain, nsIObserver *aOb
pref = getPrefName(aDomain); // aDomain == nsnull only possible failure, trapped above
rv = _convertRes(PREF_UnregisterCallback(pref, NotifyObserver, pCallback));
if (NS_SUCCEEDED(rv)) {
NS_RELEASE(pCallback->pObserver);
nsMemory::Free(pCallback);
// Remove this observer from our array so that nobody else can remove
// what we're trying to remove ourselves right now.
mObservers->RemoveElementAt(i);
mObserverDomains.RemoveCStringAt(i);
NS_RELEASE(pCallback->pObserver);
nsMemory::Free(pCallback);
}
return rv;
}
@ -803,20 +805,22 @@ void nsPrefBranch::freeObserverList(void)
if (count > 0) {
PRInt32 i;
nsCAutoString domain;
for (i = 0; i < count; i++) {
for (i = 0; i < count; ++i) {
pCallback = (PrefCallbackData *)mObservers->ElementAt(i);
if (pCallback) {
mObserverDomains.CStringAt(i, domain);
// We must pass a fully qualified preference name to remove the callback
pref = getPrefName(domain.get()); // can't fail because domain must be valid
// Remove this observer from our array so that nobody else can remove
// what we're trying to remove right now.
mObservers->ReplaceElementAt(nsnull, i);
PREF_UnregisterCallback(pref, NotifyObserver, pCallback);
NS_RELEASE(pCallback->pObserver);
nsMemory::Free(pCallback);
}
}
// now empty the observer arrays in bulk
mObservers->Clear();
// now empty the observer domains array in bulk
mObserverDomains.Clear();
}
delete mObservers;