mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 16:22:00 +00:00
Bug 1425930: Handle Broadcast()->Notify() calling RemoveObserver() r=froyd
This commit is contained in:
parent
80358d8b5d
commit
27aae0dbeb
@ -57,7 +57,17 @@ public:
|
||||
*/
|
||||
bool RemoveObserver(Observer<T>* aObserver)
|
||||
{
|
||||
return mObservers.RemoveElement(aObserver);
|
||||
if (mObservers.RemoveElement(aObserver)) {
|
||||
if (!mBroadcastCopy.IsEmpty()) {
|
||||
// Annoyingly, someone could RemoveObserver() an item on the list
|
||||
// while we're in a Broadcast()'s Notify() call.
|
||||
auto i = mBroadcastCopy.IndexOf(aObserver);
|
||||
MOZ_ASSERT(i != mBroadcastCopy.NoIndex);
|
||||
mBroadcastCopy[i] = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t Length()
|
||||
@ -65,17 +75,27 @@ public:
|
||||
return mObservers.Length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call Notify() on each item in the list.
|
||||
* Handles the case of Notify() calling RemoveObserver()
|
||||
*/
|
||||
void Broadcast(const T& aParam)
|
||||
{
|
||||
nsTArray<Observer<T>*> observersCopy(mObservers);
|
||||
uint32_t size = observersCopy.Length();
|
||||
MOZ_ASSERT(mBroadcastCopy.IsEmpty());
|
||||
mBroadcastCopy = mObservers;
|
||||
uint32_t size = mBroadcastCopy.Length();
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
observersCopy[i]->Notify(aParam);
|
||||
// nulled if Removed during Broadcast
|
||||
if (mBroadcastCopy[i]) {
|
||||
mBroadcastCopy[i]->Notify(aParam);
|
||||
}
|
||||
}
|
||||
mBroadcastCopy.Clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
nsTArray<Observer<T>*> mObservers;
|
||||
nsTArray<Observer<T>*> mBroadcastCopy;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
Loading…
Reference in New Issue
Block a user