# HG changeset patch # User Chris Cannam # Date 1433938349 -3600 # Node ID 027d8b943be54a2827c2479e2d5d8b58591fc263 # Parent f35c1f9bfaa2dad45f7e6d2f3bdc06d97e107aa5 Do not attempt to switch from read-only to read-write mode if an error is pending (may cause mutex deadlock) diff -r f35c1f9bfaa2 -r 027d8b943be5 data/fft/FFTDataServer.cpp --- a/data/fft/FFTDataServer.cpp Wed Jun 10 13:12:06 2015 +0100 +++ b/data/fft/FFTDataServer.cpp Wed Jun 10 13:12:29 2015 +0100 @@ -902,6 +902,7 @@ if (!cache) return 0; if (!cache->haveSetColumnAt(col)) { + if (getError() != "") return false; Profiler profiler("FFTDataServer::getMagnitudeAt: filling"); #ifdef DEBUG_FFT_SERVER std::cerr << "FFTDataServer::getMagnitudeAt: calling fillColumn(" @@ -938,6 +939,7 @@ if (!cache) return false; if (!cache->haveSetColumnAt(col)) { + if (getError() != "") return false; Profiler profiler("FFTDataServer::getMagnitudesAt: filling"); fillColumn(x); } @@ -968,6 +970,7 @@ if (!cache) return 0; if (!cache->haveSetColumnAt(col)) { + if (getError() != "") return false; Profiler profiler("FFTDataServer::getNormalizedMagnitudeAt: filling"); fillColumn(x); } @@ -1000,6 +1003,7 @@ if (!cache) return false; if (!cache->haveSetColumnAt(col)) { + if (getError() != "") return false; Profiler profiler("FFTDataServer::getNormalizedMagnitudesAt: filling"); fillColumn(x); } @@ -1032,6 +1036,7 @@ if (!cache) return 0; if (!cache->haveSetColumnAt(col)) { + if (getError() != "") return false; Profiler profiler("FFTDataServer::getMaximumMagnitudeAt: filling"); fillColumn(x); } @@ -1060,6 +1065,7 @@ if (!cache) return 0; if (!cache->haveSetColumnAt(col)) { + if (getError() != "") return false; Profiler profiler("FFTDataServer::getPhaseAt: filling"); fillColumn(x); } @@ -1092,6 +1098,7 @@ if (!cache) return false; if (!cache->haveSetColumnAt(col)) { + if (getError() != "") return false; Profiler profiler("FFTDataServer::getPhasesAt: filling"); fillColumn(x); } @@ -1131,6 +1138,11 @@ } if (!cache->haveSetColumnAt(col)) { + if (getError() != "") { + real = 0; + imaginary = 0; + return; + } Profiler profiler("FFTDataServer::getValuesAt: filling"); #ifdef DEBUG_FFT_SERVER std::cerr << "FFTDataServer::getValuesAt(" << x << ", " << y << "): filling" << std::endl; @@ -1165,6 +1177,7 @@ if (!cache) return false; if (!cache->haveSetColumnAt(col)) { + if (getError() != "") return false; Profiler profiler("FFTDataServer::getValuesAt: filling"); fillColumn(x); } @@ -1395,9 +1408,19 @@ QString FFTDataServer::getError() const { - if (m_error != "") return m_error; - else if (m_fillThread) return m_fillThread->getError(); - else return ""; + QString err; + if (m_error != "") { + err = m_error; + cerr << "FFTDataServer::getError: err (server " << this << ") = " << err << endl; + } else { + MutexLocker locker(&m_fftBuffersLock, "FFTDataServer::getError"); + if (m_fillThread) { + err = m_fillThread->getError(); + cerr << "FFTDataServer::getError: err (server " << this << ", from thread " << m_fillThread + << ") = " << err << endl; + } + } + return err; } int @@ -1475,8 +1498,10 @@ try { m_server.fillColumn(int((f - start) / m_server.m_windowIncrement)); } catch (std::exception &e) { - std::cerr << "FFTDataServer::FillThread::run: exception: " << e.what() << std::endl; - m_error = e.what(); + MutexLocker locker(&m_server.m_fftBuffersLock, + "FFTDataServer::run::m_fftBuffersLock [err]"); + m_threadError = e.what(); + std::cerr << "FFTDataServer::FillThread::run: exception: " << m_threadError << " (thread = " << this << " from server " << &m_server << ")" << std::endl; m_server.fillComplete(); m_completion = 100; m_extent = end; @@ -1524,8 +1549,10 @@ try { m_server.fillColumn(int((f - start) / m_server.m_windowIncrement)); } catch (std::exception &e) { - std::cerr << "FFTDataServer::FillThread::run: exception: " << e.what() << std::endl; - m_error = e.what(); + MutexLocker locker(&m_server.m_fftBuffersLock, + "FFTDataServer::run::m_fftBuffersLock [err]"); + m_threadError = e.what(); + std::cerr << "FFTDataServer::FillThread::run: exception: " << m_threadError << " (thread = " << this << " from server " << &m_server << ")" << std::endl; m_server.fillComplete(); m_completion = 100; m_extent = end; diff -r f35c1f9bfaa2 -r 027d8b943be5 data/fft/FFTDataServer.h --- a/data/fft/FFTDataServer.h Wed Jun 10 13:12:06 2015 +0100 +++ b/data/fft/FFTDataServer.h Wed Jun 10 13:12:29 2015 +0100 @@ -70,13 +70,13 @@ const DenseTimeValueModel *getModel() const { return m_model; } int getChannel() const { return m_channel; } WindowType getWindowType() const { return m_windower.getType(); } - int getWindowSize() const { return m_windowSize; } - int getWindowIncrement() const { return m_windowIncrement; } - int getFFTSize() const { return m_fftSize; } + int getWindowSize() const { return m_windowSize; } + int getWindowIncrement() const { return m_windowIncrement; } + int getFFTSize() const { return m_fftSize; } bool getPolar() const { return m_polar; } - int getWidth() const { return m_width; } - int getHeight() const { return m_height; } + int getWidth() const { return m_width; } + int getHeight() const { return m_height; } float getMagnitudeAt(int x, int y); float getNormalizedMagnitudeAt(int x, int y); @@ -196,6 +196,7 @@ return 0; } m_cacheVectorLock.unlock(); + if (getError() != "") return 0; if (!makeCache(c)) return 0; return getCacheReader(x, col); } @@ -230,7 +231,7 @@ void getStorageAdvice(int w, int h, bool &memory, bool &compact); - QMutex m_fftBuffersLock; + mutable QMutex m_fftBuffersLock; QWaitCondition m_condition; fftsample *m_fftInput; @@ -247,7 +248,7 @@ sv_frame_t getExtent() const { return m_extent; } int getCompletion() const { return m_completion ? m_completion : 1; } - QString getError() const { return m_error; } + QString getError() const { return m_threadError; } virtual void run(); protected: @@ -255,7 +256,7 @@ sv_frame_t m_extent; int m_completion; sv_frame_t m_fillFrom; - QString m_error; + QString m_threadError; }; bool m_exiting; diff -r f35c1f9bfaa2 -r 027d8b943be5 data/fft/FFTFileCacheReader.cpp --- a/data/fft/FFTFileCacheReader.cpp Wed Jun 10 13:12:06 2015 +0100 +++ b/data/fft/FFTFileCacheReader.cpp Wed Jun 10 13:12:29 2015 +0100 @@ -24,6 +24,8 @@ #include +//#define DEBUG_FFT_FILE_CACHE_READER 1 + // The underlying matrix has height (m_height * 2 + 1). In each // column we store magnitude at [0], [2] etc and phase at [1], [3] @@ -44,7 +46,9 @@ writer->getWidth(), writer->getHeight() * 2 + m_factorSize)) { -// cerr << "FFTFileCacheReader: storage type is " << (storageType == FFTCache::Compact ? "Compact" : storageType == Polar ? "Polar" : "Rectangular") << endl; +#ifdef DEBUG_FFT_FILE_CACHE_READER + cerr << "FFTFileCacheReader: storage type is " << (m_storageType == FFTCache::Compact ? "Compact" : m_storageType == FFTCache::Polar ? "Polar" : "Rectangular") << endl; +#endif } FFTFileCacheReader::~FFTFileCacheReader()