OSDN Git Service

Implemented a method to disables update signals from the FileList model. This will...
authorlordmulder <mulder2@gmx.de>
Sat, 5 May 2012 19:56:14 +0000 (21:56 +0200)
committerlordmulder <mulder2@gmx.de>
Sat, 5 May 2012 19:56:14 +0000 (21:56 +0200)
doc/Changelog.html
src/Config.h
src/Dialog_MainWindow.cpp
src/Dialog_WorkingBanner.cpp
src/Model_FileList.cpp
src/Model_FileList.h
src/Thread_FileAnalyzer.cpp
src/Thread_FileAnalyzer_Task.cpp
src/Thread_FileAnalyzer_Task.h

index d820e5a..765bede 100644 (file)
@@ -20,6 +20,7 @@ a:visited { color: #0000EE; }
 <li>Added Swedish translation, thanks to Åke Engelbrektson &lt;eson57@gmail.com&gt;
 <li>Implemented multi-threading in initialization code for faster application startup
 <li>Implemented multi-threading in file analyzer for faster file import
+<li>Fixed a potential crash (stack overflow) when adding a huge number of files
 </ul><br>
 
 <a name="4.04"></a>Changes between v4.03 and v4.04 [2012-04-26]:<br><ul>
index 93d089a..cd58fae 100644 (file)
@@ -30,7 +30,7 @@
 #define VER_LAMEXP_MINOR_LO                                    5
 #define VER_LAMEXP_TYPE                                                Alpha
 #define VER_LAMEXP_PATCH                                       1
-#define VER_LAMEXP_BUILD                                       1005
+#define VER_LAMEXP_BUILD                                       1008
 
 ///////////////////////////////////////////////////////////////////////////////
 // Tool versions (minimum expected versions!)
index 122aa07..2b0c9ec 100644 (file)
@@ -519,7 +519,22 @@ void MainWindow::addFiles(const QStringList &files)
        connect(analyzer, SIGNAL(fileAnalyzed(AudioFileModel)), m_fileListModel, SLOT(addFile(AudioFileModel)), Qt::QueuedConnection);
        connect(m_banner, SIGNAL(userAbort()), analyzer, SLOT(abortProcess()), Qt::DirectConnection);
 
-       m_banner->show(tr("Adding file(s), please wait..."), analyzer);
+       try
+       {
+               m_fileListModel->setBlockUpdates(true);
+               m_banner->show(tr("Adding file(s), please wait..."), analyzer);
+       }
+       catch(...)
+       {
+               /* ignore any exceptions that may occur */
+       }
+
+       m_fileListModel->setBlockUpdates(false);
+       qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
+       sourceFileView->update();
+       qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
+       sourceFileView->scrollToBottom();
+       qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
 
        if(analyzer->filesDenied())
        {
@@ -539,7 +554,6 @@ void MainWindow::addFiles(const QStringList &files)
        }
 
        LAMEXP_DELETE(analyzer);
-       sourceFileView->scrollToBottom();
        m_banner->close();
 }
 
index cd5d7e8..9584469 100644 (file)
@@ -50,7 +50,7 @@ WorkingBanner::WorkingBanner(QWidget *parent)
 
        //Start animation
        m_working = new QMovie(":/images/Busy.gif");
-       m_working->setSpeed(25);
+       m_working->setSpeed(50);
        labelWorking->setMovie(m_working);
        m_working->start();
 
index eee4733..f733fbd 100644 (file)
@@ -40,6 +40,7 @@
 
 FileListModel::FileListModel(void)
 :
+       m_blockUpdates(false),
        m_fileIcon(":/icons/page_white_cd.png")
 {
 }
@@ -138,26 +139,28 @@ void FileListModel::addFile(const QString &filePath)
 {
        QFileInfo fileInfo(filePath);
        const QString key = MAKE_KEY(fileInfo.canonicalFilePath()); 
+       const bool flag = (!m_blockUpdates);
 
        if(!m_fileStore.contains(key))
        {
-               beginInsertRows(QModelIndex(), m_fileList.count(), m_fileList.count());
+               if(flag) beginInsertRows(QModelIndex(), m_fileList.count(), m_fileList.count());
                m_fileStore.insert(key, AudioFileModel(fileInfo.canonicalFilePath(), fileInfo.baseName()));
                m_fileList.append(key);
-               endInsertRows();
+               if(flag) endInsertRows();
        }
 }
 
 void FileListModel::addFile(const AudioFileModel &file)
 {
        const QString key = MAKE_KEY(file.filePath()); 
+       const bool flag = (!m_blockUpdates);
 
        if(!m_fileStore.contains(key))
        {
-               beginInsertRows(QModelIndex(), m_fileList.count(), m_fileList.count());
+               if(flag) beginInsertRows(QModelIndex(), m_fileList.count(), m_fileList.count());
                m_fileStore.insert(key, file);
                m_fileList.append(key);
-               endInsertRows();
+               if(flag) endInsertRows();
        }
 }
 
index 2b09e2d..5384c3e 100644 (file)
@@ -65,11 +65,19 @@ public:
        }
        CsvError;
 
+       //Speed hacks
+       void setBlockUpdates(bool flag)
+       {
+               m_blockUpdates = flag;
+               if(!flag) reset();
+       }
+
 public slots:
        void addFile(const QString &filePath);
        void addFile(const AudioFileModel &file);
 
 private:
+       bool m_blockUpdates;
        QList<QString> m_fileList;
        QHash<QString, AudioFileModel> m_fileStore;
        const QIcon m_fileIcon;
index 545c0d5..2b0c171 100644 (file)
@@ -143,13 +143,18 @@ void FileAnalyzer::run()
 
                        while(!pool->tryStart(task))
                        {
-                               AnalyzeTask::waitForOneThread(1250);
+                               if(!AnalyzeTask::waitForOneThread(1250))
+                               {
+                                       qWarning("FileAnalyzer::run() -> Timeout !!!");
+                               }
                                
                                if(m_abortFlag)
                                {
                                        LAMEXP_DELETE(task);
                                        break;
                                }
+
+                               QThread::yieldCurrentThread();
                        }
 
                        if(m_abortFlag)
index 0b70971..fa5b46a 100644 (file)
@@ -80,7 +80,7 @@ AnalyzeTask::AnalyzeTask(const QString &inputFile, const QString &templateFile,
 AnalyzeTask::~AnalyzeTask(void)
 {
        QWriteLocker lock(&s_lock);
-       s_threadIdx_finished = qMax(s_threadIdx_finished, m_threadIdx + 1);
+       s_threadIdx_finished = qMax(s_threadIdx_finished, m_threadIdx + 1ui64);
        s_waitCond.wakeAll();
 }
 
@@ -88,7 +88,23 @@ AnalyzeTask::~AnalyzeTask(void)
 // Thread Main
 ////////////////////////////////////////////////////////////
 
-void AnalyzeTask::run(void)
+void AnalyzeTask::run()
+{
+       try
+       {
+               run_ex();
+       }
+       catch(...)
+       {
+               qWarning("WARNING: Caught an in exception AnalyzeTask thread!");
+       }
+
+       QWriteLocker lock(&s_lock);
+       s_threadIdx_finished = qMax(s_threadIdx_finished, m_threadIdx + 1ui64);
+       s_waitCond.wakeAll();
+}
+
+void AnalyzeTask::run_ex(void)
 {
        int fileType = fileTypeNormal;
        QString currentFile = QDir::fromNativeSeparators(m_inputFile);
@@ -707,7 +723,10 @@ void AnalyzeTask::waitForPreviousThreads(void)
                }
                lock.unlock();
 
-               waitForOneThread(1250);
+               if(!AnalyzeTask::waitForOneThread(1250))
+               {
+                       qWarning("AnalyzeTask::waitForPreviousThreads -> Timeout !!!");
+               }
        }
 }
 
index 6f54100..2cbb4ae 100644 (file)
@@ -54,20 +54,22 @@ public:
        static unsigned int filesCueSheet(void);
 
        //Wait till the next running thread terminates
-       static void waitForOneThread(unsigned long timeout)
+       static __forceinline bool waitForOneThread(unsigned long timeout)
        {
+               bool ret = false;
                s_waitMutex.lock();
-               s_waitCond.wait(&s_waitMutex, timeout);
+               ret = s_waitCond.wait(&s_waitMutex, timeout);
                s_waitMutex.unlock();
+               return ret;
        }
 
-       void run(void);
-
 signals:
        void fileSelected(const QString &fileName);
        void fileAnalyzed(const AudioFileModel &file);
 
 protected:
+       void run(void);
+       void run_ex(void);
 
 private:
        enum cover_t