changeset 1242:b10bd0611d16

Fix various "model deleted with no aboutToDelete notification" warnings (and one associated potential memory leak)
author Chris Cannam
date Wed, 22 Feb 2017 12:01:39 +0000
parents c2e923aa4015
children d5af42f08ba3
files layer/Colour3DPlotLayer.cpp layer/SpectrogramLayer.cpp layer/SpectrogramLayer.h
diffstat 3 files changed, 38 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/layer/Colour3DPlotLayer.cpp	Wed Feb 22 09:53:58 2017 +0000
+++ b/layer/Colour3DPlotLayer.cpp	Wed Feb 22 12:01:39 2017 +0000
@@ -70,6 +70,7 @@
 Colour3DPlotLayer::~Colour3DPlotLayer()
 {
     invalidateRenderers();
+    if (m_peakCache) m_peakCache->aboutToDelete();
     delete m_peakCache;
 }
 
@@ -135,6 +136,8 @@
 void
 Colour3DPlotLayer::setModel(const DenseThreeDimensionalModel *model)
 {
+    SVDEBUG << "Colour3DPlotLayer::setModel(" << model << ")" << endl;
+    
     if (m_model == model) return;
     const DenseThreeDimensionalModel *oldModel = m_model;
     m_model = model;
@@ -155,6 +158,7 @@
         m_peakResolution = 128;
     }
 
+    if (m_peakCache) m_peakCache->aboutToDelete();
     delete m_peakCache;
     m_peakCache = 0;
 
@@ -177,6 +181,7 @@
                                 sv_frame_t /* endFrame */)
 {
     //!!! should do this only if the range is visible
+    if (m_peakCache) m_peakCache->aboutToDelete();
     delete m_peakCache;
     m_peakCache = 0;
     
--- a/layer/SpectrogramLayer.cpp	Wed Feb 22 09:53:58 2017 +0000
+++ b/layer/SpectrogramLayer.cpp	Wed Feb 22 12:01:39 2017 +0000
@@ -132,10 +132,23 @@
 SpectrogramLayer::~SpectrogramLayer()
 {
     invalidateRenderers();
+    deleteDerivedModels();
+}
+
+void
+SpectrogramLayer::deleteDerivedModels()
+{
+    if (m_fftModel) m_fftModel->aboutToDelete();
+    if (m_peakCache) m_peakCache->aboutToDelete();
+    if (m_wholeCache) m_wholeCache->aboutToDelete();
 
     delete m_fftModel;
     delete m_peakCache;
     delete m_wholeCache;
+
+    m_fftModel = 0;
+    m_peakCache = 0;
+    m_wholeCache = 0;
 }
 
 pair<ColourScaleType, double>
@@ -1339,46 +1352,45 @@
 void
 SpectrogramLayer::recreateFFTModel()
 {
-#ifdef DEBUG_SPECTROGRAM
-    cerr << "SpectrogramLayer::recreateFFTModel called" << endl;
-#endif
+    SVDEBUG << "SpectrogramLayer::recreateFFTModel called" << endl;
 
     if (!m_model || !m_model->isOK()) {
         emit sliceableModelReplaced(m_fftModel, 0);
-        delete m_fftModel;
-        delete m_peakCache;
-        delete m_wholeCache;
-        m_fftModel = 0;
-        m_peakCache = 0;
-        m_wholeCache = 0;
+        deleteDerivedModels();
         return;
     }
 
-    FFTModel *oldModel = m_fftModel;
-
-    m_fftModel = new FFTModel(m_model,
-                              m_channel,
-                              m_windowType,
-                              m_windowSize,
-                              getWindowIncrement(),
-                              getFFTSize());
-
+    if (m_fftModel) m_fftModel->aboutToDelete();
+    
+    if (m_peakCache) m_peakCache->aboutToDelete();
     delete m_peakCache;
     m_peakCache = 0;
 
+    if (m_wholeCache) m_wholeCache->aboutToDelete();
     delete m_wholeCache;
     m_wholeCache = 0;
     
-    if (!m_fftModel->isOK()) {
+    FFTModel *newModel = new FFTModel(m_model,
+                                      m_channel,
+                                      m_windowType,
+                                      m_windowSize,
+                                      getWindowIncrement(),
+                                      getFFTSize());
+
+    if (!newModel->isOK()) {
         QMessageBox::critical
             (0, tr("FFT cache failed"),
              tr("Failed to create the FFT model for this spectrogram.\n"
                 "There may be insufficient memory or disc space to continue."));
+        delete newModel;
         delete m_fftModel;
         m_fftModel = 0;
         return;
     }
 
+    FFTModel *oldModel = m_fftModel;
+    m_fftModel = newModel;
+
     if (canStoreWholeCache()) { // i.e. if enough memory
         m_wholeCache = new Dense3DModelPeakCache(m_fftModel, 1);
         m_peakCache = new Dense3DModelPeakCache(m_wholeCache, m_peakCacheDivisor);
@@ -1387,7 +1399,6 @@
     }
 
     emit sliceableModelReplaced(oldModel, m_fftModel);
-
     delete oldModel;
 }
 
--- a/layer/SpectrogramLayer.h	Wed Feb 22 09:53:58 2017 +0000
+++ b/layer/SpectrogramLayer.h	Wed Feb 22 12:01:39 2017 +0000
@@ -320,6 +320,8 @@
     mutable ViewRendererMap m_renderers;
     Colour3DPlotRenderer *getRenderer(LayerGeometryProvider *) const;
     void invalidateRenderers();
+
+    void deleteDerivedModels();
     
     void paintWithRenderer(LayerGeometryProvider *v, QPainter &paint, QRect rect) const;