From 1b0cdc74f24815d77c8e0c7a6fbf51c4f71f45fe Mon Sep 17 00:00:00 2001 From: hogliux Date: Mon, 20 Aug 2018 09:39:25 +0100 Subject: [PATCH] DSP: Ensured that FFTW is initialised and destroyed in a thread-safe way --- modules/juce_dsp/frequency/juce_FFT.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/modules/juce_dsp/frequency/juce_FFT.cpp b/modules/juce_dsp/frequency/juce_FFT.cpp index 2fb5e4c03b..34778f889c 100644 --- a/modules/juce_dsp/frequency/juce_FFT.cpp +++ b/modules/juce_dsp/frequency/juce_FFT.cpp @@ -641,6 +641,8 @@ struct FFTWImpl : public FFT::Instance FFTWImpl (size_t orderToUse, DynamicLibrary&& libraryToUse, const Symbols& symbols) : fftwLibrary (std::move (libraryToUse)), fftw (symbols), order (static_cast (orderToUse)) { + ScopedLock lock (getFFTWPlanLock()); + auto n = (1u << order); HeapBlock> in (n), out (n); @@ -653,6 +655,8 @@ struct FFTWImpl : public FFT::Instance ~FFTWImpl() override { + ScopedLock lock (getFFTWPlanLock()); + fftw.destroy_fftw (c2cForward); fftw.destroy_fftw (c2cInverse); fftw.destroy_fftw (r2c); @@ -697,6 +701,15 @@ struct FFTWImpl : public FFT::Instance FloatVectorOperations::multiply ((float*) inputOutputData, 1.0f / static_cast (n), (int) n); } + //============================================================================== + // fftw's plan_* and destroy_* methods are NOT thread safe. So we need to share + // a lock between all instances of FFTWImpl + static CriticalSection& getFFTWPlanLock() noexcept + { + static CriticalSection cs; + return cs; + } + //============================================================================== DynamicLibrary fftwLibrary; Symbols fftw;