☠☠ backed out by 1f0b7e9a6450 ☠ ☠ | |
author | Randell Jesup <rjesup@jesup.org> |
Mon, 21 May 2018 10:35:08 -0400 | |
changeset 419166 | 9d111a95cfbbe2dea1427d22ab342a584d9c8af6 |
parent 419165 | 63b24cc63ecaa5cde91b448d1b5066a1b1bad3aa |
child 419167 | f7b8d0d06d29026e5604d3bf8725820a681f36e0 |
push id | 34029 |
push user | shindli@mozilla.com |
push date | Mon, 21 May 2018 21:30:22 +0000 |
treeherder | mozilla-central@51f2535c7974 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | froyd |
bugs | 1425930 |
milestone | 62.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/xpcom/ds/Observer.h +++ b/xpcom/ds/Observer.h @@ -52,32 +52,50 @@ public: } /** * Remove the observer from the observer list. * @return Whether the observer has been found in the list. */ 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 != mBroadcastCopy.NoIndex); + mBroadcastCopy[i] = nullptr; + return true; + } + return false; } uint32_t Length() { 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 #endif // mozilla_Observer_h