Changeset 238181 in webkit


Ignore:
Timestamp:
Nov 14, 2018 9:50:36 AM (5 years ago)
Author:
youenn@apple.com
Message:

Allow to remove MediaStreamPrivate observers when iterating over observers
https://bugs.webkit.org/show_bug.cgi?id=187256

Reviewed by Eric Carlson.

Migrate the observer list from a Vector to a HashSet.
This is more robust to multiple observing and keeping of order of observers is not required.
Copy the set of observers to a vector before iterating over it.
This allows to remove an observer while iterating, which is now used in UserMediaRequest.

Covered by existing tests.

  • Modules/mediastream/UserMediaRequest.cpp:

(WebCore::UserMediaRequest::mediaStreamIsReady):

  • platform/mediastream/MediaStreamPrivate.cpp:

(WebCore::MediaStreamPrivate::addObserver):
(WebCore::MediaStreamPrivate::removeObserver):
(WebCore::MediaStreamPrivate::forEachObserver const):
(WebCore::MediaStreamPrivate::updateActiveState):
(WebCore::MediaStreamPrivate::addTrack):
(WebCore::MediaStreamPrivate::removeTrack):
(WebCore::MediaStreamPrivate::characteristicsChanged):

  • platform/mediastream/MediaStreamPrivate.h:
Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r238180 r238181  
     12018-11-14  Youenn Fablet  <youenn@apple.com>
     2
     3        Allow to remove MediaStreamPrivate observers when iterating over observers
     4        https://bugs.webkit.org/show_bug.cgi?id=187256
     5
     6        Reviewed by Eric Carlson.
     7
     8        Migrate the observer list from a Vector to a HashSet.
     9        This is more robust to multiple observing and keeping of order of observers is not required.
     10        Copy the set of observers to a vector before iterating over it.
     11        This allows to remove an observer while iterating, which is now used in UserMediaRequest.
     12
     13        Covered by existing tests.
     14
     15        * Modules/mediastream/UserMediaRequest.cpp:
     16        (WebCore::UserMediaRequest::mediaStreamIsReady):
     17        * platform/mediastream/MediaStreamPrivate.cpp:
     18        (WebCore::MediaStreamPrivate::addObserver):
     19        (WebCore::MediaStreamPrivate::removeObserver):
     20        (WebCore::MediaStreamPrivate::forEachObserver const):
     21        (WebCore::MediaStreamPrivate::updateActiveState):
     22        (WebCore::MediaStreamPrivate::addTrack):
     23        (WebCore::MediaStreamPrivate::removeTrack):
     24        (WebCore::MediaStreamPrivate::characteristicsChanged):
     25        * platform/mediastream/MediaStreamPrivate.h:
     26
    1272018-11-14  Youenn Fablet  <youenn@apple.com>
    228
  • trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp

    r238091 r238181  
    366366    stream->document()->setHasCaptureMediaStreamTrack();
    367367    m_promise.resolve(WTFMove(stream));
    368     // We are in an observer iterator loop, we do not want to change the observers within this loop.
    369     callOnMainThread([stream = WTFMove(m_pendingActivationMediaStream)] { });
     368    m_pendingActivationMediaStream = nullptr;
    370369}
    371370
  • trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp

    r233829 r238181  
    8585void MediaStreamPrivate::addObserver(MediaStreamPrivate::Observer& observer)
    8686{
    87     m_observers.append(&observer);
     87    m_observers.add(&observer);
    8888}
    8989
    9090void MediaStreamPrivate::removeObserver(MediaStreamPrivate::Observer& observer)
    9191{
    92     size_t pos = m_observers.find(&observer);
    93     if (pos != notFound)
    94         m_observers.remove(pos);
     92    m_observers.remove(&observer);
     93}
     94
     95void MediaStreamPrivate::forEachObserver(const WTF::Function<void(Observer&)>& apply) const
     96{
     97    for (auto* observer : copyToVector(m_observers)) {
     98        if (!m_observers.contains(observer))
     99            continue;
     100        apply(*observer);
     101    }
    95102}
    96103
     
    119126
    120127    if (notifyClientOption == NotifyClientOption::Notify) {
    121         for (auto& observer : m_observers)
    122             observer->activeStatusChanged();
     128        forEachObserver([](auto& observer) {
     129            observer.activeStatusChanged();
     130        });
    123131    }
    124132}
     
    133141
    134142    if (notifyClientOption == NotifyClientOption::Notify) {
    135         for (auto& observer : m_observers)
    136             observer->didAddTrack(*track.get());
     143        forEachObserver([&track](auto& observer) {
     144            observer.didAddTrack(*track.get());
     145        });
    137146    }
    138147
     
    149158
    150159    if (notifyClientOption == NotifyClientOption::Notify) {
    151         for (auto& observer : m_observers)
    152             observer->didRemoveTrack(track);
     160        forEachObserver([&track](auto& observer) {
     161            observer.didRemoveTrack(track);
     162        });
    153163    }
    154164
     
    257267void MediaStreamPrivate::characteristicsChanged()
    258268{
    259     for (auto& observer : m_observers)
    260         observer->characteristicsChanged();
     269    forEachObserver([](auto& observer) {
     270        observer.characteristicsChanged();
     271    });
    261272}
    262273
  • trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.h

    r233829 r238181  
    118118
    119119    void scheduleDeferredTask(Function<void ()>&&);
     120    void forEachObserver(const WTF::Function<void(Observer&)>&) const;
    120121
    121     Vector<Observer*> m_observers;
     122    HashSet<Observer*> m_observers;
    122123    String m_id;
    123124    MediaStreamTrackPrivate* m_activeVideoTrack { nullptr };
Note: See TracChangeset for help on using the changeset viewer.