]> git.sesse.net Git - vlc/blobdiff - modules/gui/skins2/commands/async_queue.cpp
CACA: use key thread (partially fix #3661)
[vlc] / modules / gui / skins2 / commands / async_queue.cpp
index 25529d046aaf9499bef4f67e20d00d225c61cb03..759ff6a6e5d37fa65d3ee7b67145aa3b6eb8f616 100644 (file)
@@ -1,11 +1,11 @@
 /*****************************************************************************
  * async_queue.cpp
  *****************************************************************************
- * Copyright (C) 2003 VideoLAN (Centrale Réseaux) and its contributors
+ * Copyright (C) 2003 the VideoLAN team
  * $Id$
  *
  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
- *          Olivier Teulière <ipkiss@via.ecp.fr>
+ *          Olivier Teulière <ipkiss@via.ecp.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 #include "async_queue.hpp"
 #include "../src/os_timer.hpp"
 
 
-AsyncQueue::AsyncQueue( intf_thread_t *pIntf ): SkinObject( pIntf )
+AsyncQueue::AsyncQueue( intf_thread_t *pIntf ): SkinObject( pIntf ),
+    m_cmdFlush( this )
 {
     // Initialize the mutex
-    vlc_mutex_init( pIntf, &m_lock );
+    vlc_mutex_init( &m_lock );
 
     // Create a timer
     OSFactory *pOsFactory = OSFactory::instance( pIntf );
-    m_pTimer = pOsFactory->createOSTimer( Callback( this, &doFlush ) );
+    m_pTimer = pOsFactory->createOSTimer( m_cmdFlush );
 
     // Flush the queue every 10 ms
     m_pTimer->start( 10, false );
@@ -66,38 +67,45 @@ AsyncQueue *AsyncQueue::instance( intf_thread_t *pIntf )
 
 void AsyncQueue::destroy( intf_thread_t *pIntf )
 {
-    if( pIntf->p_sys->p_queue )
-    {
-        delete pIntf->p_sys->p_queue;
-        pIntf->p_sys->p_queue = NULL;
-    }
+    delete pIntf->p_sys->p_queue;
+    pIntf->p_sys->p_queue = NULL;
 }
 
 
-void AsyncQueue::push( const CmdGenericPtr &rcCommand )
+void AsyncQueue::push( const CmdGenericPtr &rcCommand, bool removePrev )
 {
+    vlc_mutex_lock( &m_lock );
+
+    if( removePrev )
+    {
+        // Remove the commands of the same type
+        remove( rcCommand.get()->getType(), rcCommand );
+    }
     m_cmdList.push_back( rcCommand );
+
+    vlc_mutex_unlock( &m_lock );
 }
 
 
-void AsyncQueue::remove( const string &rType )
+void AsyncQueue::remove( const string &rType, const CmdGenericPtr &rcCommand )
 {
-    vlc_mutex_lock( &m_lock );
-
-    list<CmdGenericPtr>::iterator it;
-    for( it = m_cmdList.begin(); it != m_cmdList.end(); it++ )
+    cmdList_t::iterator it;
+    for( it = m_cmdList.begin(); it != m_cmdList.end(); /* nothing */ )
     {
-        // Remove the command if it is of the given type
-        if( (*it).get()->getType() == rType )
+        // Remove the command if it is of the given type and the command
+        // doesn't disagree. Note trickery to avoid skipping entries
+        // while maintaining iterator validity.
+
+        if( (*it).get()->getType() == rType &&
+            rcCommand.get()->checkRemove( (*it).get() ) )
         {
-            list<CmdGenericPtr>::iterator itNew = it;
-            itNew++;
+            cmdList_t::iterator itNew = it;
+            ++itNew;
             m_cmdList.erase( it );
             it = itNew;
         }
+        else ++it;
     }
-
-    vlc_mutex_unlock( &m_lock );
 }
 
 
@@ -129,9 +137,8 @@ void AsyncQueue::flush()
 }
 
 
-void AsyncQueue::doFlush( SkinObject *pObj )
+void AsyncQueue::CmdFlush::execute()
 {
-    AsyncQueue *pThis = (AsyncQueue*)pObj;
     // Flush the queue
-    pThis->flush();
+    m_pParent->flush();
 }