Ignore:
Timestamp:
Sep 3, 2010, 11:02:51 AM (15 years ago)
Author:
[email protected]
Message:

2010-09-03 Alexey Proskuryakov <[email protected]>

Reviewed by Darin Adler.

https://bugs.webkit.org/show_bug.cgi?id=45135
<rdar://problem/7823714> TCMalloc_PageHeap doesn't hold a mutex while manipulating shared data

  • wtf/FastMalloc.cpp: (WTF::TCMalloc_PageHeap::initializeScavenger): Make sure to create a non-recursive mutex regardless of platform default, so that we can assert that it's held (this is for platforms that don't have libdispatch). (WTF::TCMalloc_PageHeap::signalScavenger): Assert that the mutex is held, so we can look at m_scavengeThreadActive. For platforms that have libdispatch, assert that pageheap_lock is held. (WTF::TCMalloc_PageHeap::periodicScavenge): Make sure that pageheap_lock is held before manipulating m_scavengeThreadActive. Otherwise, there is an obvious race condition, and we can make unbalanced calls to dispatch_resume().
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/wtf/FastMalloc.cpp

    r66538 r66741  
    14931493void TCMalloc_PageHeap::initializeScavenger()
    14941494{
    1495   pthread_mutex_init(&m_scavengeMutex, 0);
    1496   pthread_cond_init(&m_scavengeCondition, 0);
    1497   m_scavengeThreadActive = true;
    1498   pthread_t thread;
    1499   pthread_create(&thread, 0, runScavengerThread, this);
     1495    // Create a non-recursive mutex.
     1496#if PTHREAD_MUTEX_NORMAL == PTHREAD_MUTEX_DEFAULT
     1497    pthread_mutex_init(&m_scavengeMutex, 0);
     1498#else
     1499    pthread_mutexattr_t attr;
     1500    pthread_mutexattr_init(&attr);
     1501    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
     1502
     1503    pthread_mutex_init(&m_scavengeMutex, &attr);
     1504
     1505    pthread_mutexattr_destroy(&attr);
     1506#endif
     1507
     1508    pthread_cond_init(&m_scavengeCondition, 0);
     1509    m_scavengeThreadActive = true;
     1510    pthread_t thread;
     1511    pthread_create(&thread, 0, runScavengerThread, this);
    15001512}
    15011513
     
    15111523ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
    15121524{
    1513   if (!m_scavengeThreadActive && shouldScavenge())
    1514     pthread_cond_signal(&m_scavengeCondition);
     1525    // m_scavengeMutex should be held before accessing m_scavengeThreadActive.
     1526    ASSERT(pthread_mutex_trylock(m_scavengeMutex));
     1527    if (!m_scavengeThreadActive && shouldScavenge())
     1528        pthread_cond_signal(&m_scavengeCondition);
    15151529}
    15161530
     
    15291543ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
    15301544{
    1531   if (!m_scavengingScheduled && shouldScavenge()) {
    1532     m_scavengingScheduled = true;
    1533     dispatch_resume(m_scavengeTimer);
    1534   }
     1545    ASSERT(IsHeld(pageheap_lock));
     1546    if (!m_scavengingScheduled && shouldScavenge()) {
     1547        m_scavengingScheduled = true;
     1548        dispatch_resume(m_scavengeTimer);
     1549    }
    15351550}
    15361551
     
    23982413void TCMalloc_PageHeap::periodicScavenge()
    23992414{
    2400   {
    24012415    SpinLockHolder h(&pageheap_lock);
    24022416    pageheap->scavenge();
    2403   }
    2404 
    2405   if (!shouldScavenge()) {
    2406     m_scavengingScheduled = false;
    2407     dispatch_suspend(m_scavengeTimer);
    2408   }
     2417
     2418    if (!shouldScavenge()) {
     2419        m_scavengingScheduled = false;
     2420        dispatch_suspend(m_scavengeTimer);
     2421    }
    24092422}
    24102423#endif // HAVE(DISPATCH_H)
Note: See TracChangeset for help on using the changeset viewer.