Changeset 18588 in webkit


Ignore:
Timestamp:
Jan 4, 2007 12:52:59 PM (17 years ago)
Author:
beidson
Message:

Reviewed and landed by Brady

Allow a PageCache that is pending release to be resurrected by its
HistoryItem instead of creating a new PageCache. This avoids the
the condition of having two PageCaches for the same HistoryItem, one
current and one pending release but not yet released, which was causing
this and other bugs before.


Replaced the vector of PageCaches pending release with a set of
HistoryItems that are pending release of their PageCache.

  • history/HistoryItem.cpp: (WebCore::HistoryItem::HistoryItem): (WebCore::HistoryItem::setHasPageCache): Check for an existing PageCache pending release, and if found, resurrect it by canceling the release. (WebCore::HistoryItem::pageCache): Return 0 if the PageCache is pending release. (WebCore::itemsWithPendingPageCacheToRelease): Renamed pendingPageCacheToRelease to this. This method now returns a HashSet of HistoryItems that have scheduled their PageCaches for release. (WebCore::HistoryItem::releasePageCachesOrReschedule): Renamed releasePageCache to this. (WebCore::HistoryItem::releasePageCache): Added. Actually closes and releases the PageCache. (WebCore::HistoryItem::releaseAllPendingPageCaches): Rolled closeObjectsInPendingPageCaches into this method. (WebCore::HistoryItem::scheduleRelease): (WebCore::HistoryItem::cancelRelease): Added.
  • history/HistoryItem.h: Removed unused declaration of scheduleReleaseTimer()
  • history/HistoryItemTimer.cpp: (WebCore::HistoryItemTimer::HistoryItemTimer): (WebCore::HistoryItemTimer::callReleasePageCachesOrReschedule):
  • history/HistoryItemTimer.h:
Location:
trunk/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r18587 r18588  
     12007-01-04  Mitz Pettel  <mitz@webkit.org>
     2
     3        Reviewed and landed by Brady
     4
     5        - fix http://bugs.webkit.org/show_bug.cgi?id=12087
     6          REGRESSION: Reproducible crash going back in Back/Forward history
     7
     8        Allow a PageCache that is pending release to be resurrected by its
     9        HistoryItem instead of creating a new PageCache. This avoids the
     10        the condition of having two PageCaches for the same HistoryItem, one
     11        current and one pending release but not yet released, which was causing
     12        this and other bugs before.
     13       
     14        Replaced the vector of PageCaches pending release with a set of
     15        HistoryItems that are pending release of their PageCache.
     16
     17        * history/HistoryItem.cpp:
     18        (WebCore::HistoryItem::HistoryItem):
     19        (WebCore::HistoryItem::setHasPageCache): Check for an existing PageCache
     20        pending release, and if found, resurrect it by canceling the release.
     21        (WebCore::HistoryItem::pageCache): Return 0 if the PageCache is pending
     22        release.
     23        (WebCore::itemsWithPendingPageCacheToRelease): Renamed pendingPageCacheToRelease
     24        to this. This method now returns a HashSet of HistoryItems that have scheduled
     25        their PageCaches for release.
     26        (WebCore::HistoryItem::releasePageCachesOrReschedule): Renamed releasePageCache
     27        to this.
     28        (WebCore::HistoryItem::releasePageCache): Added. Actually closes and releases
     29        the PageCache.
     30        (WebCore::HistoryItem::releaseAllPendingPageCaches): Rolled closeObjectsInPendingPageCaches
     31        into this method.
     32        (WebCore::HistoryItem::scheduleRelease):
     33        (WebCore::HistoryItem::cancelRelease): Added.
     34        * history/HistoryItem.h: Removed unused declaration of scheduleReleaseTimer()
     35        * history/HistoryItemTimer.cpp:
     36        (WebCore::HistoryItemTimer::HistoryItemTimer):
     37        (WebCore::HistoryItemTimer::callReleasePageCachesOrReschedule):
     38        * history/HistoryItemTimer.h:
     39
    1402007-01-04  David Hyatt  <hyatt@apple.com>
    241
  • trunk/WebCore/history/HistoryItem.cpp

    r18541 r18588  
    4444HistoryItem::HistoryItem()
    4545    : m_lastVisitedTime(0)
     46    , m_pageCacheIsPendingRelease(false)
    4647    , m_isTargetItem(false)
    4748    , m_alwaysAttemptToUsePageCache(false)
     
    5556    , m_title(title)
    5657    , m_lastVisitedTime(time)
     58    , m_pageCacheIsPendingRelease(false)
    5759    , m_isTargetItem(false)
    5860    , m_alwaysAttemptToUsePageCache(false)
     
    6769    , m_title(title)
    6870    , m_lastVisitedTime(0)
     71    , m_pageCacheIsPendingRelease(false)
    6972    , m_isTargetItem(false)
    7073    , m_alwaysAttemptToUsePageCache(false)
     
    8184    , m_title(title)
    8285    , m_lastVisitedTime(0)
     86    , m_pageCacheIsPendingRelease(false)
    8387    , m_isTargetItem(false)
    8488    , m_alwaysAttemptToUsePageCache(false)
     
    104108    , m_scrollPoint(item.m_scrollPoint)
    105109    , m_subItems(item.m_subItems.size())
     110    , m_pageCacheIsPendingRelease(false)
    106111    , m_isTargetItem(item.m_isTargetItem)
    107112    , m_alwaysAttemptToUsePageCache(item.m_alwaysAttemptToUsePageCache)
     
    128133    LOG(PageCache, "WebCorePageCache - HistoryItem %p setting has page cache to %s", this, hasCache ? "TRUE" : "FALSE" );
    129134       
    130     if (hasCache && !m_pageCache)
    131         m_pageCache = new PageCache;
    132     if (!hasCache && m_pageCache)
     135    if (hasCache) {
     136        if (!m_pageCache)
     137            m_pageCache = new PageCache;
     138        else if (m_pageCacheIsPendingRelease)
     139            cancelRelease();
     140    } else if (m_pageCache)
    133141        scheduleRelease();
    134142}
     
    354362PageCache* HistoryItem::pageCache()
    355363{
     364    if (m_pageCacheIsPendingRelease)
     365        return 0;
    356366    return m_pageCache.get();
    357367}
     
    427437}
    428438
    429 static Vector<RefPtr<PageCache> >& pendingPageCacheToRelease()
     439static HashSet<RefPtr<HistoryItem> >& itemsWithPendingPageCacheToRelease()
    430440{
    431441    // We keep this on the heap because otherwise, at app shutdown, we run into the "static destruction order fiasco"
    432442    // where the vector is torn down, the PageCaches destroyed, and all havok may break loose.  Instead, we just leak at shutdown
    433443    // since nothing here persists
    434     static Vector<RefPtr<PageCache> >* pendingPageCacheToRelease = new Vector<RefPtr<PageCache> >;
    435     return *pendingPageCacheToRelease;
    436 }
    437 
    438 void HistoryItem::releasePageCache()
     444    static HashSet<RefPtr<HistoryItem> >* itemsWithPendingPageCacheToRelease = new HashSet<RefPtr<HistoryItem> >;
     445    return *itemsWithPendingPageCacheToRelease;
     446}
     447
     448void HistoryItem::releasePageCachesOrReschedule()
    439449{
    440450    double loadDelta = currentTime() - FrameLoader::timeOfLastCompletedLoad();
     
    443453    // FIXME: This size of 42 pending caches to release seems awfully arbitrary
    444454    // Wonder if anyone knows the rationalization
    445     if ((userDelta < 0.5 || loadDelta < 1.25) && pendingPageCacheToRelease().size() < 42) {
    446         LOG(PageCache, "WebCorePageCache: Postponing releasePageCache() - %f since last load, %f since last input, %i objects pending release", loadDelta, userDelta, pendingPageCacheToRelease().size());
     455    if ((userDelta < 0.5 || loadDelta < 1.25) && itemsWithPendingPageCacheToRelease().size() < 42) {
     456        LOG(PageCache, "WebCorePageCache: Postponing releasePageCachesOrReschedule() - %f since last load, %f since last input, %i objects pending release", loadDelta, userDelta, itemsWithPendingPageCacheToRelease().size());
    447457        timer().schedule();
    448458        return;
    449459    }
    450460
    451     LOG(PageCache, "WebCorePageCache: Releasing page caches - %f seconds since last load, %f since last input, %i objects pending release", loadDelta, userDelta, pendingPageCacheToRelease().size());
     461    LOG(PageCache, "WebCorePageCache: Releasing page caches - %f seconds since last load, %f since last input, %i objects pending release", loadDelta, userDelta, itemsWithPendingPageCacheToRelease().size());
    452462    releaseAllPendingPageCaches();
    453463}
    454464
    455 void closeObjectsInPendingPageCaches()
    456 {
    457     size_t size = pendingPageCacheToRelease().size();
    458     for (size_t i = 0; i < size; ++i)
    459         pendingPageCacheToRelease()[i]->close();
     465void HistoryItem::releasePageCache()
     466{
     467    m_pageCache->close();
     468    m_pageCache = 0;
     469    m_pageCacheIsPendingRelease = false;
    460470}
    461471
     
    463473{
    464474    timer().invalidate();
    465     closeObjectsInPendingPageCaches();
    466     pendingPageCacheToRelease().clear();
     475
     476    HashSet<RefPtr<HistoryItem> >::iterator i = itemsWithPendingPageCacheToRelease().begin();
     477    HashSet<RefPtr<HistoryItem> >::iterator end = itemsWithPendingPageCacheToRelease().end();
     478    for (; i != end; ++i)
     479        (*i)->releasePageCache();
     480
     481    itemsWithPendingPageCacheToRelease().clear();
    467482}
    468483
     
    474489        timer().schedule();
    475490
    476     if (m_pageCache) {
    477         pendingPageCacheToRelease().append(m_pageCache);
    478         m_pageCache = 0;
    479     }
    480 }
    481 
     491    if (m_pageCache && !m_pageCacheIsPendingRelease) {
     492        m_pageCacheIsPendingRelease = true;
     493        itemsWithPendingPageCacheToRelease().add(this);
     494    }
     495}
     496
     497void HistoryItem::cancelRelease()
     498{
     499    itemsWithPendingPageCacheToRelease().remove(this);
     500    m_pageCacheIsPendingRelease = false;
     501}
    482502#ifndef NDEBUG
    483503void HistoryItem::print() const
  • trunk/WebCore/history/HistoryItem.h

    r18541 r18588  
    144144
    145145    void scheduleRelease();
     146    void cancelRelease();
     147    void releasePageCache(); 
    146148   
    147149#ifndef NDEBUG
     
    151153private:
    152154    HistoryItem(const HistoryItem&);
    153     static void scheduleReleaseTimer();
    154     static void releasePageCache();
     155    static void releasePageCachesOrReschedule();
    155156   
    156157    String m_urlString;
     
    167168   
    168169    HistoryItemVector m_subItems;
     170    bool m_pageCacheIsPendingRelease;
    169171    RefPtr<PageCache> m_pageCache;
    170172   
  • trunk/WebCore/history/HistoryItemTimer.cpp

    r18541 r18588  
    3434
    3535HistoryItemTimer::HistoryItemTimer()
    36     : m_timer(this, &HistoryItemTimer::callReleasePageCache)
     36    : m_timer(this, &HistoryItemTimer::callReleasePageCachesOrReschedule)
    3737{
    3838}
     
    5353}
    5454
    55 void HistoryItemTimer::callReleasePageCache(Timer<HistoryItemTimer>*)
     55void HistoryItemTimer::callReleasePageCachesOrReschedule(Timer<HistoryItemTimer>*)
    5656{
    57     HistoryItem::releasePageCache();
     57    HistoryItem::releasePageCachesOrReschedule();
    5858}
    5959
  • trunk/WebCore/history/HistoryItemTimer.h

    r18541 r18588  
    4242
    4343private:
    44     void callReleasePageCache(Timer<HistoryItemTimer>*);
     44    void callReleasePageCachesOrReschedule(Timer<HistoryItemTimer>*);
    4545    Timer<HistoryItemTimer> m_timer;
    4646};
Note: See TracChangeset for help on using the changeset viewer.