зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1425930 - Handle Broadcast()->Notify() calling RemoveObserver(). r=froyd
--HG-- extra : rebase_source : 87dc3560125bbb6c77215777753c9fbc2a34e7f6
This commit is contained in:
Родитель
53c7c73179
Коммит
ceedbeadd3
|
@ -57,7 +57,15 @@ public:
|
||||||
*/
|
*/
|
||||||
bool RemoveObserver(Observer<T>* aObserver)
|
bool RemoveObserver(Observer<T>* aObserver)
|
||||||
{
|
{
|
||||||
return mObservers.RemoveElement(aObserver);
|
if (mObservers.RemoveElement(aObserver)) {
|
||||||
|
// 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 != NoIndex);
|
||||||
|
mBroadcastCopy[i] = nullptr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Length()
|
uint32_t Length()
|
||||||
|
@ -65,17 +73,27 @@ public:
|
||||||
return mObservers.Length();
|
return mObservers.Length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call Notify() on each item in the list.
|
||||||
|
* Handles the case of Notify() calling RemoveObserver()
|
||||||
|
*/
|
||||||
void Broadcast(const T& aParam)
|
void Broadcast(const T& aParam)
|
||||||
{
|
{
|
||||||
nsTArray<Observer<T>*> observersCopy(mObservers);
|
MOZ_ASSERT(mBroadcastCopy.Empty());
|
||||||
uint32_t size = observersCopy.Length();
|
mBroadcastCopy = mObservers;
|
||||||
|
uint32_t size = mBroadcastCopy.Length();
|
||||||
for (uint32_t i = 0; i < size; ++i) {
|
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:
|
protected:
|
||||||
nsTArray<Observer<T>*> mObservers;
|
nsTArray<Observer<T>*> mObservers;
|
||||||
|
nsTArray<Observer<T>*> mBroadcastCopy;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
Загрузка…
Ссылка в новой задаче