[vlmc-devel] Fix potential deadlock when parsing metadata.
Hugo Beauzée-Luyssen
git at videolan.org
Mon Feb 24 20:08:45 CET 2014
vlmc | branch: ibackend | Hugo Beauzée-Luyssen <hugo at beauzee.fr> | Mon Feb 24 19:46:20 2014 +0200| [b5f2e911189b378f885f8a007c7eec918ea7a011] | committer: Hugo Beauzée-Luyssen
Fix potential deadlock when parsing metadata.
Turns out setTime might process synchronously :(
> http://git.videolan.org/gitweb.cgi/vlmc.git/?a=commit;h=b5f2e911189b378f885f8a007c7eec918ea7a011
---
src/Backend/VLC/EventWaiter.cpp | 8 ++++++--
src/Backend/VLC/EventWaiter.h | 10 +++++++---
src/Backend/VLC/VLCSource.cpp | 4 ++--
3 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/src/Backend/VLC/EventWaiter.cpp b/src/Backend/VLC/EventWaiter.cpp
index 19165d9..480990a 100644
--- a/src/Backend/VLC/EventWaiter.cpp
+++ b/src/Backend/VLC/EventWaiter.cpp
@@ -24,13 +24,15 @@
using namespace Backend::VLC;
-EventWaiter::EventWaiter( LibVLCpp::MediaPlayer* mediaPlayer )
+EventWaiter::EventWaiter( LibVLCpp::MediaPlayer* mediaPlayer, bool startLocked )
: m_mediaPlayer( mediaPlayer )
, m_validationCallback( NULL )
, m_found( true )
+ , m_startLocked( startLocked )
{
+ if ( startLocked == true )
+ m_mutex.lock();
m_mediaPlayer->registerEvents( &EventWaiter::eventsCallback, this );
- m_mutex.lock();
}
EventWaiter::~EventWaiter()
@@ -47,6 +49,8 @@ EventWaiter::add(libvlc_event_type_t event)
EventWaiter::Result
EventWaiter::wait(unsigned long timeoutMs)
{
+ if ( m_startLocked == false )
+ m_mutex.lock();
if ( m_waitCond.wait( &m_mutex, timeoutMs ) == false )
{
m_mutex.unlock();
diff --git a/src/Backend/VLC/EventWaiter.h b/src/Backend/VLC/EventWaiter.h
index bf73511..2c7ef98 100644
--- a/src/Backend/VLC/EventWaiter.h
+++ b/src/Backend/VLC/EventWaiter.h
@@ -43,10 +43,13 @@ public:
* \li <whatever action that will lead to an asynchronous event>
* \li we->wait(...);
*
- * @warning If the event comes synchronously, this will deadlock. But if
- * it happens synchronously, why would you need this at all?
+ * @param startLocked Specify if the EventWaiter should immediatly lock the mutex
+ * If this is false, mutex will be locked when wait() is called. This should
+ * be set to false when the function leading to the event might process synchronously
+ * and if the event will be triggered again (for instance, time & position events)
+ *
*/
- EventWaiter( LibVLCpp::MediaPlayer* mediaPlayer );
+ EventWaiter(LibVLCpp::MediaPlayer* mediaPlayer , bool startLocked);
~EventWaiter();
enum Result
@@ -71,6 +74,7 @@ private:
QMutex m_mutex;
ValidationCallback m_validationCallback;
bool m_found;
+ bool m_startLocked;
};
} //VLC
diff --git a/src/Backend/VLC/VLCSource.cpp b/src/Backend/VLC/VLCSource.cpp
index e56d3cc..89e2e31 100644
--- a/src/Backend/VLC/VLCSource.cpp
+++ b/src/Backend/VLC/VLCSource.cpp
@@ -70,7 +70,7 @@ VLCSource::preparse()
VmemRenderer* renderer = new VmemRenderer( m_backend, this, NULL );
LibVLCpp::MediaPlayer* mediaPlayer = renderer->mediaPlayer();
{
- EventWaiter ew( mediaPlayer );
+ EventWaiter ew( mediaPlayer, true );
ew.add( libvlc_MediaPlayerLengthChanged );
renderer->start();
if ( ew.wait( 3000 ) != EventWaiter::Success )
@@ -120,7 +120,7 @@ VLCSource::computeSnapshot( VmemRenderer* renderer )
Q_ASSERT( m_snapshot == NULL );
LibVLCpp::MediaPlayer* mediaPlayer = renderer->mediaPlayer();
{
- EventWaiter ew( mediaPlayer );
+ EventWaiter ew( mediaPlayer, false );
ew.add( libvlc_MediaPlayerPositionChanged );
ew.setValidationCallback( &checkTimeChanged );
renderer->setTime( m_length / 3 );
More information about the Vlmc-devel
mailing list