Bug 1187152 (part 2) - Replace nsBaseHashtable::Enumerate() calls in modules/ with iterators. r=froydnj.

This commit is contained in:
Nicholas Nethercote 2015-11-22 18:52:40 -08:00
parent f3b832777a
commit 7f26939fe8

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -635,8 +636,8 @@ NS_IMETHODIMP nsPrefBranch::RemoveObserver(const char *aDomain, nsIObserver *aOb
// it hasn't been already.
//
// It's important that we don't touch mObservers in any way -- even a Get()
// which retuns null might cause the hashtable to resize itself, which will
// break the Enumerator in freeObserverList.
// which returns null might cause the hashtable to resize itself, which will
// break the iteration in freeObserverList.
if (mFreeingObserverList)
return NS_OK;
@ -686,32 +687,20 @@ void nsPrefBranch::NotifyObserver(const char *newpref, void *data)
NS_ConvertASCIItoUTF16(suffix).get());
}
PLDHashOperator
FreeObserverFunc(PrefCallback *aKey,
nsAutoPtr<PrefCallback> &aCallback,
void *aArgs)
{
// Calling NS_RELEASE below might trigger a call to
// nsPrefBranch::RemoveObserver, since some classes remove themselves from
// the pref branch on destruction. We don't need to worry about this causing
// double-frees, however, because freeObserverList sets mFreeingObserverList
// to true, which prevents RemoveObserver calls from doing anything.
nsPrefBranch *prefBranch = aCallback->GetPrefBranch();
const char *pref = prefBranch->getPrefName(aCallback->GetDomain().get());
PREF_UnregisterCallback(pref, nsPrefBranch::NotifyObserver, aCallback);
return PL_DHASH_REMOVE;
}
void nsPrefBranch::freeObserverList(void)
{
// We need to prevent anyone from modifying mObservers while we're
// enumerating over it. In particular, some clients will call
// RemoveObserver() when they're destructed; we need to keep those calls from
// touching mObservers.
// We need to prevent anyone from modifying mObservers while we're iterating
// over it. In particular, some clients will call RemoveObserver() when
// they're removed and destructed via the iterator; we set
// mFreeingObserverList to keep those calls from touching mObservers.
mFreeingObserverList = true;
mObservers.Enumerate(&FreeObserverFunc, nullptr);
for (auto iter = mObservers.Iter(); !iter.Done(); iter.Next()) {
nsAutoPtr<PrefCallback>& callback = iter.Data();
nsPrefBranch *prefBranch = callback->GetPrefBranch();
const char *pref = prefBranch->getPrefName(callback->GetDomain().get());
PREF_UnregisterCallback(pref, nsPrefBranch::NotifyObserver, callback);
iter.Remove();
}
mFreeingObserverList = false;
}