Mercurial > hg > svcore
changeset 458:f60360209e5c
* Fix race condition in FFTFileCache when reading from the same FFT model
from multiple threads (e.g. when applying more than one plugin at once)
author | Chris Cannam |
---|---|
date | Wed, 15 Oct 2008 12:08:02 +0000 |
parents | ef14acd6d102 |
children | 6441b31b37ac |
files | data/fft/FFTFileCache.cpp data/fft/FFTFileCache.h |
diffstat | 2 files changed, 28 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/data/fft/FFTFileCache.cpp Tue Oct 14 16:36:35 2008 +0000 +++ b/data/fft/FFTFileCache.cpp Wed Oct 15 12:08:02 2008 +0000 @@ -72,16 +72,21 @@ MutexLocker locker(&m_writeMutex, "FFTFileCache::resize::m_writeMutex"); m_mfc->resize(width, height * 2 + m_factorSize); - if (m_readbuf) { - delete[] m_readbuf; - m_readbuf = 0; + + { + MutexLocker locker(&m_readbufMutex, "FFTFileCache::resize::m_readMutex"); + if (m_readbuf) { + delete[] m_readbuf; + m_readbuf = 0; + } } + if (m_writebuf) { delete[] m_writebuf; } m_writebuf = new char[(height * 2 + m_factorSize) * m_mfc->getCellSize()]; } - + void FFTFileCache::reset() { @@ -302,7 +307,7 @@ } void -FFTFileCache::populateReadBuf(size_t x) const +FFTFileCache::populateReadBuf(size_t x) const // m_readbufMutex already held { Profiler profiler("FFTFileCache::populateReadBuf", false);
--- a/data/fft/FFTFileCache.h Tue Oct 14 16:36:35 2008 +0000 +++ b/data/fft/FFTFileCache.h Wed Oct 15 12:08:02 2008 +0000 @@ -62,31 +62,43 @@ mutable size_t m_readbufWidth; float getFromReadBufStandard(size_t x, size_t y) const { + m_readbufMutex.lock(); if (m_readbuf && (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) { - return ((float *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y]; + float v = ((float *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y]; + m_readbufMutex.unlock(); + return v; } else { populateReadBuf(x); + m_readbufMutex.unlock(); return getFromReadBufStandard(x, y); } } float getFromReadBufCompactUnsigned(size_t x, size_t y) const { + m_readbufMutex.lock(); if (m_readbuf && (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) { - return ((uint16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y]; + float v = ((uint16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y]; + m_readbufMutex.unlock(); + return v; } else { populateReadBuf(x); + m_readbufMutex.unlock(); return getFromReadBufCompactUnsigned(x, y); } } float getFromReadBufCompactSigned(size_t x, size_t y) const { + m_readbufMutex.lock(); if (m_readbuf && (m_readbufCol == x || (m_readbufWidth > 1 && m_readbufCol+1 == x))) { - return ((int16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y]; + float v = ((int16_t *)m_readbuf)[(x - m_readbufCol) * m_mfc->getHeight() + y]; + m_readbufMutex.unlock(); + return v; } else { populateReadBuf(x); + m_readbufMutex.unlock(); return getFromReadBufCompactSigned(x, y); } } @@ -99,6 +111,7 @@ if (m_storageType != Compact) { return getFromReadBufStandard(col, h - 1); } else { + m_readbufMutex.lock(); union { float f; uint16_t u[2]; @@ -111,6 +124,7 @@ size_t ix = (col - m_readbufCol) * m_mfc->getHeight() + h; factor.u[0] = ((uint16_t *)m_readbuf)[ix - 2]; factor.u[1] = ((uint16_t *)m_readbuf)[ix - 1]; + m_readbufMutex.unlock(); return factor.f; } } @@ -133,6 +147,7 @@ MatrixFile *m_mfc; QMutex m_writeMutex; + mutable QMutex m_readbufMutex; StorageType m_storageType; size_t m_factorSize; };