[vlc-devel] commit: skins2: avoid deadlock when audio-visual is used ( accounts for vlc often but not always hanging in this case) (Erwan Tulou )

git version control git at videolan.org
Mon Aug 24 18:07:57 CEST 2009


vlc | branch: master | Erwan Tulou <erwan10 at videolan.org> | Sat Aug 22 15:01:57 2009 +0200| [64a6e968de15c50e48018cfbb7aff939388cb02d] | committer: Erwan Tulou 

skins2: avoid deadlock when audio-visual is used (accounts for vlc often but not always hanging in this case)

Audio-visual holds the audio_mixer lock during its initialization phase which includes initialization of the vout.
On the other hand, skins polls every 10ms to check change in the audio volume (this also requires holding the audio_mixer lock)
This leads to a frequent deadlock at the skins level.

The patch stops polling w.r.t volume and rather reacts on change signalled by the core via a callback. This makes deadlock occurence almost nil.

A long term solution could be that 1/ audio_visual doesn't keep on holding the lock during vout initialisation and 2/ skins stops polling every 10ms for a whole bunch of things (rather use callbacks as qt4 does)

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=64a6e968de15c50e48018cfbb7aff939388cb02d
---

 modules/gui/skins2/commands/cmd_audio.cpp |    8 ++++++
 modules/gui/skins2/commands/cmd_audio.hpp |   17 +++++++++++++
 modules/gui/skins2/src/vlcproc.cpp        |   36 +++++++++++++++++++++++++----
 modules/gui/skins2/src/vlcproc.hpp        |    8 ++++++
 4 files changed, 64 insertions(+), 5 deletions(-)

diff --git a/modules/gui/skins2/commands/cmd_audio.cpp b/modules/gui/skins2/commands/cmd_audio.cpp
index 6d2b7e5..ec7878c 100644
--- a/modules/gui/skins2/commands/cmd_audio.cpp
+++ b/modules/gui/skins2/commands/cmd_audio.cpp
@@ -22,6 +22,7 @@
  *****************************************************************************/
 
 #include "cmd_audio.hpp"
+#include "../src/vlcproc.hpp"
 #include <vlc_aout.h>
 #include <string>
 
@@ -53,3 +54,10 @@ void CmdSetEqualizer::execute()
     }
 }
 
+void CmdVolumeChanged::execute()
+{
+    VlcProc* p_VlcProc = getIntf()->p_sys->p_vlcProc;
+
+    p_VlcProc->refreshVolume();
+}
+
diff --git a/modules/gui/skins2/commands/cmd_audio.hpp b/modules/gui/skins2/commands/cmd_audio.hpp
index f3fba5b..c1e5c83 100644
--- a/modules/gui/skins2/commands/cmd_audio.hpp
+++ b/modules/gui/skins2/commands/cmd_audio.hpp
@@ -46,4 +46,21 @@ class CmdSetEqualizer: public CmdGeneric
 };
 
 
+/// Command to enable/disable the equalizer
+class CmdVolumeChanged: public CmdGeneric
+{
+    public:
+        CmdVolumeChanged( intf_thread_t *pIntf ) : CmdGeneric( pIntf ) {}
+        virtual ~CmdVolumeChanged() {}
+
+        /// This method does the real job of the command
+        virtual void execute();
+
+        /// Return the type of the command
+        virtual string getType() const { return "set volume"; }
+
+    private:
+};
+
+
 #endif
diff --git a/modules/gui/skins2/src/vlcproc.cpp b/modules/gui/skins2/src/vlcproc.cpp
index a475795..af4654a 100644
--- a/modules/gui/skins2/src/vlcproc.cpp
+++ b/modules/gui/skins2/src/vlcproc.cpp
@@ -47,6 +47,7 @@
 #include "../commands/cmd_vars.hpp"
 #include "../commands/cmd_dialogs.hpp"
 #include "../commands/cmd_update_item.hpp"
+#include "../commands/cmd_audio.hpp"
 #include "../utils/var_bool.hpp"
 #include <sstream>
 
@@ -137,6 +138,9 @@ VlcProc::VlcProc( intf_thread_t *pIntf ): SkinObject( pIntf ),
     // so they must put commands in the queue and NOT do anything else
     // (X11 calls are not reentrant)
 
+    // Called when volume sound changes
+    var_AddCallback( pIntf->p_libvlc, "volume-change",
+                     onVolumeChanged, this );
     // Called when the playlist changes
     var_AddCallback( pIntf->p_sys->p_playlist, "intf-change",
                      onIntfChange, this );
@@ -180,6 +184,8 @@ VlcProc::~VlcProc()
 
     interaction_Unregister( getIntf() );
 
+    var_DelCallback( getIntf()->p_libvlc, "volume-change",
+                     onVolumeChanged, this );
     var_DelCallback( getIntf()->p_sys->p_playlist, "intf-change",
                      onIntfChange, this );
     var_DelCallback( getIntf()->p_sys->p_playlist, "playlist-item-append",
@@ -252,6 +258,14 @@ void VlcProc::refreshAudio()
         pFilters = config_GetPsz( getIntf(), "audio-filter" );
     }
 
+    // Refresh the equalizer variable
+    VarBoolImpl *pVarEqualizer = (VarBoolImpl*)m_cVarEqualizer.get();
+    pVarEqualizer->set( pFilters && strstr( pFilters, "equalizer" ) );
+    free( pFilters );
+}
+
+void VlcProc::refreshVolume()
+{
     // Refresh sound volume
     audio_volume_t volume;
     aout_VolumeGet( getIntf()->p_sys->p_playlist, &volume );
@@ -261,11 +275,6 @@ void VlcProc::refreshAudio()
     // Set the mute variable
     VarBoolImpl *pVarMute = (VarBoolImpl*)m_cVarMute.get();
     pVarMute->set( volume == 0 );
-
-    // Refresh the equalizer variable
-    VarBoolImpl *pVarEqualizer = (VarBoolImpl*)m_cVarEqualizer.get();
-    pVarEqualizer->set( pFilters && strstr( pFilters, "equalizer" ) );
-    free( pFilters );
 }
 
 void VlcProc::refreshPlaylist()
@@ -372,6 +381,23 @@ void VlcProc::refreshInput()
     }
 }
 
+int VlcProc::onVolumeChanged( vlc_object_t *pObj, const char *pVariable,
+                           vlc_value_t oldVal, vlc_value_t newVal,
+                           void *pParam )
+{
+    VlcProc *pThis = (VlcProc*)pParam;
+
+    // Create a playtree notify command (for new style playtree)
+    CmdVolumeChanged *pCmd = new CmdVolumeChanged( pThis->getIntf() );
+
+    // Push the command in the asynchronous command queue
+    AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
+    pQueue->push( CmdGenericPtr( pCmd ) );
+
+    return VLC_SUCCESS;
+}
+
+
 int VlcProc::onIntfChange( vlc_object_t *pObj, const char *pVariable,
                            vlc_value_t oldVal, vlc_value_t newVal,
                            void *pParam )
diff --git a/modules/gui/skins2/src/vlcproc.hpp b/modules/gui/skins2/src/vlcproc.hpp
index 42e0d95..da70a5e 100644
--- a/modules/gui/skins2/src/vlcproc.hpp
+++ b/modules/gui/skins2/src/vlcproc.hpp
@@ -85,6 +85,9 @@ class VlcProc: public SkinObject
         /// Indicate whether the embedded video output is currently used
         bool isVoutUsed() const { return m_pVout != NULL; }
 
+        /// Refresh Volume
+        void refreshVolume();
+
     protected:
         // Protected because it is a singleton
         VlcProc( intf_thread_t *pIntf );
@@ -154,6 +157,11 @@ class VlcProc: public SkinObject
         /// Update the stream name variable
         void updateStreamName();
 
+        /// Callback for volume variable
+        static int onVolumeChanged( vlc_object_t *pObj, const char *pVariable,
+                                    vlc_value_t oldVal, vlc_value_t newVal,
+                                    void *pParam );
+
         /// Callback for intf-change variable
         static int onIntfChange( vlc_object_t *pObj, const char *pVariable,
                                  vlc_value_t oldVal, vlc_value_t newVal,




More information about the vlc-devel mailing list