Changeset 95929 in webkit


Ignore:
Timestamp:
Sep 25, 2011 6:40:04 PM (13 years ago)
Author:
mrowe@apple.com
Message:

<rdar://problem/10177824> IconDatabase’s use of ThreadCondition leads to assertion failures in the face of spurious wakeups

It's possible for ThreadCondition::wait to return spuriously without the condition having been signaled.
When that happens we should immediately return to waiting rather than doing our normal work, as some of that
work relies on wakeSyncThread having been called to signal the condition.

Reviewed by Sam Weinig.

  • loader/icon/IconDatabase.cpp:

(WebCore::IconDatabase::IconDatabase):
(WebCore::IconDatabase::wakeSyncThread): Note that we have work for the sync thread to do.
(WebCore::IconDatabase::syncThreadMainLoop): If we were woken with no work to do, immediately
go back to waiting on the condition variable. Otherwise, reset m_syncThreadHasWorkToDo and then
do that work. We also switch to moving m_disabledSuddenTerminationForSyncThread immediately in to
our local shouldReenableSuddenTermination variable since it can be updated by other threads while
we don't hold the lock. This makes it inappropriate to make assumptions about its value after dropping
and reacquiring the lock.

  • loader/icon/IconDatabase.h:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r95926 r95929  
     12011-09-25  Mark Rowe  <mrowe@apple.com>
     2
     3        <rdar://problem/10177824> IconDatabase’s use of ThreadCondition leads to assertion failures in the face of spurious wakeups
     4
     5        It's possible for ThreadCondition::wait to return spuriously without the condition having been signaled.
     6        When that happens we should immediately return to waiting rather than doing our normal work, as some of that
     7        work relies on wakeSyncThread having been called to signal the condition.
     8
     9        Reviewed by Sam Weinig.
     10
     11        * loader/icon/IconDatabase.cpp:
     12        (WebCore::IconDatabase::IconDatabase):
     13        (WebCore::IconDatabase::wakeSyncThread): Note that we have work for the sync thread to do.
     14        (WebCore::IconDatabase::syncThreadMainLoop): If we were woken with no work to do, immediately
     15        go back to waiting on the condition variable. Otherwise, reset m_syncThreadHasWorkToDo and then
     16        do that work. We also switch to moving m_disabledSuddenTerminationForSyncThread immediately in to
     17        our local shouldReenableSuddenTermination variable since it can be updated by other threads while
     18        we don't hold the lock. This makes it inappropriate to make assumptions about its value after dropping
     19        and reacquiring the lock.
     20        * loader/icon/IconDatabase.h:
     21
    1222011-09-25  Dan Bernstein  <mitz@apple.com>
    223
  • trunk/Source/WebCore/loader/icon/IconDatabase.cpp

    r95646 r95929  
    768768    , m_removeIconsRequested(false)
    769769    , m_iconURLImportComplete(false)
     770    , m_syncThreadHasWorkToDo(false)
    770771    , m_disabledSuddenTerminationForSyncThread(false)
    771772    , m_initialPruningComplete(false)
     
    819820    }
    820821
     822    m_syncThreadHasWorkToDo = true;
    821823    m_syncCondition.signal();
    822824}
     
    13511353    ASSERT_ICON_SYNC_THREAD();
    13521354
    1353     bool shouldReenableSuddenTermination = false;
    1354 
    13551355    m_syncLock.lock();
     1356
     1357    bool shouldReenableSuddenTermination = m_disabledSuddenTerminationForSyncThread;
     1358    m_disabledSuddenTerminationForSyncThread = false;
    13561359
    13571360    // It's possible thread termination is requested before the main loop even starts - in that case, just skip straight to cleanup
     
    14281431            // wakeSyncThread function. Any time we wait on the condition, we also have
    14291432            // to enableSuddenTermation, after doing the next batch of work.
    1430             ASSERT(m_disabledSuddenTerminationForSyncThread);
    14311433            enableSuddenTermination();
    1432             m_disabledSuddenTerminationForSyncThread = false;
    1433         }
    1434 
    1435         m_syncCondition.wait(m_syncLock);
    1436 
     1434        }
     1435
     1436        while (!m_syncThreadHasWorkToDo)
     1437            m_syncCondition.wait(m_syncLock);
     1438
     1439        m_syncThreadHasWorkToDo = false;
     1440
     1441        ASSERT(m_disabledSuddenTerminationForSyncThread);
    14371442        shouldReenableSuddenTermination = true;
     1443        m_disabledSuddenTerminationForSyncThread = false;
    14381444    }
    14391445
     
    14471453        // wakeSyncThread function. Any time we wait on the condition, we also have
    14481454        // to enableSuddenTermation, after doing the next batch of work.
    1449         ASSERT(m_disabledSuddenTerminationForSyncThread);
    14501455        enableSuddenTermination();
     1456
     1457        MutexLocker locker(m_syncLock);
    14511458        m_disabledSuddenTerminationForSyncThread = false;
    14521459    }
  • trunk/Source/WebCore/loader/icon/IconDatabase.h

    r92551 r95929  
    145145    bool m_isEnabled;
    146146    bool m_privateBrowsingEnabled;
    147    
     147
    148148    mutable Mutex m_syncLock;
    149149    ThreadCondition m_syncCondition;
     
    155155    bool m_removeIconsRequested;
    156156    bool m_iconURLImportComplete;
     157    bool m_syncThreadHasWorkToDo;
    157158    bool m_disabledSuddenTerminationForSyncThread;
    158159
Note: See TracChangeset for help on using the changeset viewer.