Changeset 218038 in webkit


Ignore:
Timestamp:
Jun 9, 2017 7:51:05 PM (7 years ago)
Author:
commit-queue@webkit.org
Message:

Image should clear its ImageObserver* when CachedImage releases the last reference to its RefCounted<ImageObserver>
https://bugs.webkit.org/show_bug.cgi?id=173077

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2017-06-09
Reviewed by Simon Fraser.

Before dereferencing ImageObserver, CachedImage::clearImage() should check
whether it is the only object that holds a reference to this ImageObserver.
And if this is true, m_image have to clear its raw pointer to the deleted
ImageObserver by calling m_image->setImageObserver(nullptr).

  • loader/cache/CachedImage.cpp:

(WebCore::CachedImage::setBodyDataFrom):
(WebCore::CachedImage::CachedImageObserver::CachedImageObserver):
(WebCore::CachedImage::clearImage):

  • loader/cache/CachedImage.h:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r218037 r218038  
     12017-06-09  Said Abou-Hallawa  <sabouhallawa@apple.com>
     2
     3        Image should clear its ImageObserver* when CachedImage releases the last reference to its RefCounted<ImageObserver>
     4        https://bugs.webkit.org/show_bug.cgi?id=173077
     5
     6        Reviewed by Simon Fraser.
     7
     8        Before dereferencing ImageObserver, CachedImage::clearImage() should check
     9        whether it is the only object that holds a reference to this ImageObserver.
     10        And if this is true, m_image have to clear its raw pointer to the deleted
     11        ImageObserver by calling m_image->setImageObserver(nullptr).
     12
     13        * loader/cache/CachedImage.cpp:
     14        (WebCore::CachedImage::setBodyDataFrom):
     15        (WebCore::CachedImage::CachedImageObserver::CachedImageObserver):
     16        (WebCore::CachedImage::clearImage):
     17        * loader/cache/CachedImage.h:
     18
    1192017-06-09  Daniel Bates  <dabates@apple.com>
    220
  • trunk/Source/WebCore/loader/cache/CachedImage.cpp

    r218031 r218038  
    102102    m_imageObserver = image.m_imageObserver;
    103103    if (m_imageObserver)
    104         m_imageObserver->add(*this);
     104        m_imageObserver->cachedImages().add(this);
    105105
    106106    if (m_image && is<SVGImage>(*m_image))
     
    327327CachedImage::CachedImageObserver::CachedImageObserver(CachedImage& image)
    328328{
    329     m_cachedImages.reserveInitialCapacity(1);
    330     m_cachedImages.append(&image);
     329    m_cachedImages.add(&image);
    331330}
    332331
     
    368367inline void CachedImage::clearImage()
    369368{
     369    if (!m_image)
     370        return;
     371
    370372    if (m_imageObserver) {
    371         m_imageObserver->remove(*this);
     373        m_imageObserver->cachedImages().remove(this);
     374
     375        if (m_imageObserver->cachedImages().isEmpty()) {
     376            ASSERT(m_imageObserver->hasOneRef());
     377            m_image->setImageObserver(nullptr);
     378        }
     379
    372380        m_imageObserver = nullptr;
    373381    }
     382
    374383    m_image = nullptr;
    375384}
  • trunk/Source/WebCore/loader/cache/CachedImage.h

    r218031 r218038  
    121121    public:
    122122        static Ref<CachedImageObserver> create(CachedImage& image) { return adoptRef(*new CachedImageObserver(image)); }
    123         void add(CachedImage& image) { m_cachedImages.append(&image); }
    124         void remove(CachedImage& image) { m_cachedImages.removeFirst(&image); }
     123        HashSet<CachedImage*>& cachedImages() { return m_cachedImages; }
     124        const HashSet<CachedImage*>& cachedImages() const { return m_cachedImages; }
    125125
    126126    private:
     
    128128
    129129        // ImageObserver API
    130         URL sourceUrl() const override { return !m_cachedImages.isEmpty() ? m_cachedImages[0]->url() : URL(); }
     130        URL sourceUrl() const override { return !m_cachedImages.isEmpty() ? (*m_cachedImages.begin())->url() : URL(); }
    131131        void decodedSizeChanged(const Image&, long long delta) final;
    132132        void didDraw(const Image&) final;
     
    136136        void changedInRect(const Image&, const IntRect*) final;
    137137
    138         Vector<CachedImage*> m_cachedImages;
     138        HashSet<CachedImage*> m_cachedImages;
    139139    };
    140140
Note: See TracChangeset for help on using the changeset viewer.