diff options
author | Thierry Bastian <thierry.bastian@nokia.com> | 2009-08-10 11:45:24 (GMT) |
---|---|---|
committer | Thierry Bastian <thierry.bastian@nokia.com> | 2009-08-10 12:29:40 (GMT) |
commit | 18a7ff8d6319e9da2e4e5f705ce1622558a0f6b0 (patch) | |
tree | b085128aeb0a80e99bcf12dbc7d2331942f5ec32 | |
parent | 03d0c1ba491393008fb7687e77e6463379095413 (diff) | |
download | Qt-18a7ff8d6319e9da2e4e5f705ce1622558a0f6b0.zip Qt-18a7ff8d6319e9da2e4e5f705ce1622558a0f6b0.tar.gz Qt-18a7ff8d6319e9da2e4e5f705ce1622558a0f6b0.tar.bz2 |
Fixed an assert that could happen when the mediaSource is deleted
When using streaming, it could happen that the last reference to the
MediaSource is in another thread. So the objects are destroyed from
another thread. In which case we would delete QObject (ioDevice) in
another thread. That is fixed by calling deleteLater which will ensure
that they are deleted in their own thread.
Note: there was a nother assert that could happen due to a race
condition in the worker thread. That is also fixed with this patch.
Reviewed-by: jbache
-rw-r--r-- | src/3rdparty/phonon/ds9/mediaobject.cpp | 42 | ||||
-rw-r--r-- | src/3rdparty/phonon/ds9/mediaobject.h | 1 | ||||
-rw-r--r-- | src/3rdparty/phonon/phonon/mediasource.cpp | 8 |
3 files changed, 21 insertions, 30 deletions
diff --git a/src/3rdparty/phonon/ds9/mediaobject.cpp b/src/3rdparty/phonon/ds9/mediaobject.cpp index 1d0b69d..23e392c 100644 --- a/src/3rdparty/phonon/ds9/mediaobject.cpp +++ b/src/3rdparty/phonon/ds9/mediaobject.cpp @@ -57,24 +57,6 @@ namespace Phonon { } - WorkerThread::Work WorkerThread::dequeueWork() - { - QMutexLocker locker(&m_mutex); - if (m_finished) { - return Work(); - } - Work ret = m_queue.dequeue(); - - //we ensure to have the wait condition in the right state - if (m_queue.isEmpty()) { - m_waitCondition.reset(); - } else { - m_waitCondition.set(); - } - - return ret; - } - void WorkerThread::run() { while (m_finished == false) { @@ -88,11 +70,6 @@ namespace Phonon } DWORD result = ::WaitForMultipleObjects(count, handles, FALSE, INFINITE); if (result == WAIT_OBJECT_0) { - if (m_finished) { - //that's the end if the thread execution - return; - } - handleTask(); } else { //this is the event management @@ -199,18 +176,25 @@ namespace Phonon void WorkerThread::handleTask() { - const Work w = dequeueWork(); - - if (m_finished) { + QMutexLocker locker(&m_mutex); + if (m_finished || m_queue.isEmpty()) { return; } + const Work w = m_queue.dequeue(); + + //we ensure to have the wait condition in the right state + if (m_queue.isEmpty()) { + m_waitCondition.reset(); + } else { + m_waitCondition.set(); + } + HRESULT hr = S_OK; m_currentRender = w.graph; m_currentRenderId = w.id; if (w.task == ReplaceGraph) { - QMutexLocker locker(&m_mutex); HANDLE h; int index = -1; @@ -234,6 +218,9 @@ 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); @@ -252,6 +239,7 @@ 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); diff --git a/src/3rdparty/phonon/ds9/mediaobject.h b/src/3rdparty/phonon/ds9/mediaobject.h index 2c34ffc..fe52604 100644 --- a/src/3rdparty/phonon/ds9/mediaobject.h +++ b/src/3rdparty/phonon/ds9/mediaobject.h @@ -135,7 +135,6 @@ namespace Phonon }; QList<Filter> decoders; //for the state change requests }; - Work dequeueWork(); void handleTask(); Graph m_currentRender; diff --git a/src/3rdparty/phonon/phonon/mediasource.cpp b/src/3rdparty/phonon/phonon/mediasource.cpp index 0a21c87..c003af9 100644 --- a/src/3rdparty/phonon/phonon/mediasource.cpp +++ b/src/3rdparty/phonon/phonon/mediasource.cpp @@ -140,8 +140,12 @@ MediaSourcePrivate::~MediaSourcePrivate() { #ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM if (autoDelete) { - delete stream; - delete ioDevice; + //here we use deleteLater because this object + //might be destroyed from another thread + if (stream) + stream->deleteLater(); + if (ioDevice) + ioDevice->deleteLater(); } #endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM } |