changeset 543:7a66b94ef1c0

* Thread safety (fixing a crash)
author Chris Cannam
date Wed, 04 Feb 2009 10:53:38 +0000
parents 1ddab154fb9a
children 65d955c4d671
files data/fileio/CodedAudioFileReader.cpp data/fileio/CodedAudioFileReader.h
diffstat 2 files changed, 16 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/data/fileio/CodedAudioFileReader.cpp	Tue Feb 03 11:12:19 2009 +0000
+++ b/data/fileio/CodedAudioFileReader.cpp	Wed Feb 04 10:53:38 2009 +0000
@@ -333,10 +333,12 @@
         break;
 
     case CacheInMemory:
+        m_dataLock.lockForWrite();
         for (size_t s = 0; s < count; ++s) {
-            m_data.push_back(buffer[count]);
+            m_data.push_back(buffer[s]);
         }
 	MUNLOCK_SAMPLEBLOCK(m_data);
+        m_dataLock.unlock();
         break;
     }
 }
@@ -345,8 +347,9 @@
 CodedAudioFileReader::getInterleavedFrames(size_t start, size_t count,
                                            SampleBlock &frames) const
 {
-    //!!! we want to ensure this doesn't require a lock -- at the
-    // moment it does need one, but it doesn't have one...
+    // Lock is only required in CacheInMemory mode (the cache file
+    // reader is expected to be thread safe and manage its own
+    // locking)
 
     if (!m_initialised) {
         std::cerr << "CodedAudioFileReader::getInterleavedFrames: not initialised" << std::endl;
@@ -366,16 +369,17 @@
         frames.clear();
         if (!isOK()) return;
         if (count == 0) return;
+        frames.reserve(count * m_channelCount);
 
-        // slownessabounds
+        size_t idx = start * m_channelCount;
+        size_t i = 0;
 
-        for (size_t i = start; i < start + count; ++i) {
-            for (size_t ch = 0; ch < m_channelCount; ++ch) {
-                size_t index = i * m_channelCount + ch;
-                if (index >= m_data.size()) return;
-                frames.push_back(m_data[index]);
-            }
+        m_dataLock.lockForRead();
+        while (i < count * m_channelCount && idx < m_data.size()) {
+            frames.push_back(m_data[idx]);
+            ++idx;
         }
+        m_dataLock.unlock();
     }
     }
 }
--- a/data/fileio/CodedAudioFileReader.h	Tue Feb 03 11:12:19 2009 +0000
+++ b/data/fileio/CodedAudioFileReader.h	Wed Feb 04 10:53:38 2009 +0000
@@ -20,6 +20,7 @@
 
 #include <sndfile.h>
 #include <QMutex>
+#include <QReadWriteLock>
 
 class WavFileReader;
 class Serialiser;
@@ -65,6 +66,7 @@
     QMutex m_cacheMutex;
     CacheMode m_cacheMode;
     SampleBlock m_data;
+    mutable QReadWriteLock m_dataLock;
     bool m_initialised;
     Serialiser *m_serialiser;
     size_t m_fileRate;