From 507c0ff17beeddfd281a4e978c2612031ce49154 Mon Sep 17 00:00:00 2001
From: Thierry Bastian <thierry.bastian@nokia.com>
Date: Tue, 11 Aug 2009 13:16:51 +0200
Subject: Phonon: improve locking to make it safer to load a source

Task-number: 259482
---
 src/3rdparty/phonon/ds9/mediaobject.cpp | 32 ++++++++++++++++++++------------
 src/3rdparty/phonon/ds9/mediaobject.h   |  3 ++-
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/src/3rdparty/phonon/ds9/mediaobject.cpp b/src/3rdparty/phonon/ds9/mediaobject.cpp
index b163ad4..a4feef6 100644
--- a/src/3rdparty/phonon/ds9/mediaobject.cpp
+++ b/src/3rdparty/phonon/ds9/mediaobject.cpp
@@ -192,8 +192,11 @@ namespace Phonon
 
             HRESULT hr = S_OK;
 
-            m_currentRender = w.graph;
-			m_currentRenderId = w.id;
+            {
+                QMutexLocker locker(&m_currentMutex);
+                m_currentRender = w.graph;
+			    m_currentRenderId = w.id;
+            }
             if (w.task == ReplaceGraph) {
                 int index = -1;
                 for(int i = 0; i < FILTER_COUNT; ++i) {
@@ -217,9 +220,6 @@ namespace Phonon
                     m_graphHandle[index].handle = h;
                 }
             } else if (w.task == Render) {
-                //we need to unlock here because the use might trigger a call to abort
-                //which uses the same mutex
-                locker.unlock();
                 if (w.filter) {
                     //let's render pins
                     w.graph->AddFilter(w.filter, 0);
@@ -238,7 +238,6 @@ namespace Phonon
                 if (hr != E_ABORT) {
                     emit asyncRenderFinished(w.id, hr, w.graph);
                 }
-                locker.relock();
             } else if (w.task == Seek) {
                 //that's a seekrequest
                 ComPointer<IMediaSeeking> mediaSeeking(w.graph, IID_IMediaSeeking);
@@ -311,12 +310,22 @@ namespace Phonon
                 }
             }
 
-            m_currentRender = Graph();
-            m_currentRenderId = 0;
+            {
+                QMutexLocker locker(&m_currentMutex);
+                m_currentRender = Graph();
+                m_currentRenderId = 0;
+            }
         }
 
         void WorkerThread::abortCurrentRender(qint16 renderId)
         {
+            {
+                QMutexLocker locker(&m_currentMutex);
+                if (m_currentRender && m_currentRenderId == renderId) {
+                    m_currentRender->Abort();
+                }
+            }
+
             QMutexLocker locker(&m_mutex);
             bool found = false;
             for(int i = 0; !found && i < m_queue.size(); ++i) {
@@ -324,12 +333,11 @@ namespace Phonon
                 if (w.id == renderId) {
                     found = true;
                     m_queue.removeAt(i);
+                    if (m_queue.isEmpty()) {
+                        m_waitCondition.reset();
+                    }
                 }
             }
-
-            if (m_currentRender && m_currentRenderId == renderId) {
-                m_currentRender->Abort();
-            }
         }
 
         //tells the thread to stop processing
diff --git a/src/3rdparty/phonon/ds9/mediaobject.h b/src/3rdparty/phonon/ds9/mediaobject.h
index fe52604..a6beb5f 100644
--- a/src/3rdparty/phonon/ds9/mediaobject.h
+++ b/src/3rdparty/phonon/ds9/mediaobject.h
@@ -143,7 +143,8 @@ namespace Phonon
             bool m_finished;
             quint16 m_currentWorkId;
             QWinWaitCondition m_waitCondition;
-            QMutex m_mutex;
+            QMutex m_mutex; // mutex for the m_queue, m_finished and m_currentWorkId
+            QMutex m_currentMutex; //mutex for current renderer and id
 
             //this is for WaitForMultipleObjects
             struct
-- 
cgit v0.12