mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1150916 - Be sure we aren't iterating over a hashtable while it is modified in nsObserverService::UnmarkGrayStrongObservers(). r=froydnj
The QI in xpc_TryUnmarkWrappedGrayObject() might somehow trigger a GC, which in turn could destroy an observer, that would in turn call RemoveObserver() which mutates the hash table that we're enumerating.
This commit is contained in:
parent
a510c1c69c
commit
c4efa0ed24
@ -88,6 +88,18 @@ nsObserverList::FillObserverArray(nsCOMArray<nsIObserver>& aArray)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsObserverList::AppendStrongObservers(nsCOMArray<nsIObserver>& aArray)
|
||||
{
|
||||
aArray.SetCapacity(aArray.Length() + mObservers.Length());
|
||||
|
||||
for (int32_t i = mObservers.Length() - 1; i >= 0; --i) {
|
||||
if (!mObservers[i].isWeakRef) {
|
||||
aArray.AppendObject(mObservers[i].asObserver());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsObserverList::NotifyObservers(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
@ -101,18 +113,6 @@ nsObserverList::NotifyObservers(nsISupports* aSubject,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsObserverList::UnmarkGrayStrongObservers()
|
||||
{
|
||||
#if !defined(MOZILLA_XPCOMRT_API)
|
||||
for (uint32_t i = 0; i < mObservers.Length(); ++i) {
|
||||
if (!mObservers[i].isWeakRef) {
|
||||
xpc_TryUnmarkWrappedGrayObject(mObservers[i].asObserver());
|
||||
}
|
||||
}
|
||||
#endif // !defined(MOZILLA_XPCOMRT_API)
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsObserverEnumerator, nsISimpleEnumerator)
|
||||
|
||||
nsObserverEnumerator::nsObserverEnumerator(nsObserverList* aObserverList)
|
||||
|
@ -71,9 +71,8 @@ public:
|
||||
// The array is filled in last-added-first order.
|
||||
void FillObserverArray(nsCOMArray<nsIObserver>& aArray);
|
||||
|
||||
// Unmark any strongly held observers implemented in JS so the cycle
|
||||
// collector will not traverse them.
|
||||
void UnmarkGrayStrongObservers();
|
||||
// Like FillObserverArray(), but only for strongly held observers.
|
||||
void AppendStrongObservers(nsCOMArray<nsIObserver>& aArray);
|
||||
|
||||
private:
|
||||
nsTArray<ObserverRef> mObservers;
|
||||
|
@ -344,10 +344,12 @@ NS_IMETHODIMP nsObserverService::NotifyObservers(nsISupports* aSubject,
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
UnmarkGrayObserverEntry(nsObserverList* aObserverList, void* aClosure)
|
||||
AppendStrongObservers(nsObserverList* aObserverList, void* aClosure)
|
||||
{
|
||||
nsCOMArray<nsIObserver>* array = static_cast<nsCOMArray<nsIObserver>*>(aClosure);
|
||||
|
||||
if (aObserverList) {
|
||||
aObserverList->UnmarkGrayStrongObservers();
|
||||
aObserverList->AppendStrongObservers(*array);
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
@ -357,7 +359,14 @@ nsObserverService::UnmarkGrayStrongObservers()
|
||||
{
|
||||
NS_ENSURE_VALIDCALL
|
||||
|
||||
mObserverTopicTable.EnumerateEntries(UnmarkGrayObserverEntry, nullptr);
|
||||
#if !defined(MOZILLA_XPCOMRT_API)
|
||||
nsCOMArray<nsIObserver> strongObservers;
|
||||
mObserverTopicTable.EnumerateEntries(AppendStrongObservers, &strongObservers);
|
||||
|
||||
for (uint32_t i = 0; i < strongObservers.Length(); ++i) {
|
||||
xpc_TryUnmarkWrappedGrayObject(strongObservers[i]);
|
||||
}
|
||||
#endif // !defined(MOZILLA_XPCOMRT_API)
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user