1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2003 the VideoLAN team
7 * Authors: Cyril Deguet <asmax@via.ecp.fr>
8 * Olivier Teulière <ipkiss@via.ecp.fr>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 #include "async_queue.hpp"
26 #include "../src/os_factory.hpp"
27 #include "../src/os_timer.hpp"
30 AsyncQueue::AsyncQueue( intf_thread_t *pIntf ): SkinObject( pIntf ),
33 // Initialize the mutex
34 vlc_mutex_init( &m_lock );
37 OSFactory *pOsFactory = OSFactory::instance( pIntf );
38 m_pTimer = pOsFactory->createOSTimer( m_cmdFlush );
40 // Flush the queue every 10 ms
41 m_pTimer->start( 10, false );
45 AsyncQueue::~AsyncQueue()
48 vlc_mutex_destroy( &m_lock );
52 AsyncQueue *AsyncQueue::instance( intf_thread_t *pIntf )
54 if( ! pIntf->p_sys->p_queue )
57 pQueue = new AsyncQueue( pIntf );
60 // Initialization succeeded
61 pIntf->p_sys->p_queue = pQueue;
64 return pIntf->p_sys->p_queue;
68 void AsyncQueue::destroy( intf_thread_t *pIntf )
70 delete pIntf->p_sys->p_queue;
71 pIntf->p_sys->p_queue = NULL;
75 void AsyncQueue::push( const CmdGenericPtr &rcCommand, bool removePrev )
77 vlc_mutex_lock( &m_lock );
81 // Remove the commands of the same type
82 remove( rcCommand.get()->getType(), rcCommand );
84 m_cmdList.push_back( rcCommand );
86 vlc_mutex_unlock( &m_lock );
90 void AsyncQueue::remove( const string &rType, const CmdGenericPtr &rcCommand )
92 cmdList_t::iterator it;
93 for( it = m_cmdList.begin(); it != m_cmdList.end(); /* nothing */ )
95 // Remove the command if it is of the given type and the command
96 // doesn't disagree. Note trickery to avoid skipping entries
97 // while maintaining iterator validity.
99 if( (*it).get()->getType() == rType &&
100 rcCommand.get()->checkRemove( (*it).get() ) )
102 cmdList_t::iterator itNew = it;
104 m_cmdList.erase( it );
112 void AsyncQueue::flush()
116 vlc_mutex_lock( &m_lock );
118 if( m_cmdList.size() > 0 )
120 // Pop the first command from the queue
121 CmdGenericPtr cCommand = m_cmdList.front();
122 m_cmdList.pop_front();
124 // Unlock the mutex to avoid deadlocks if another thread wants to
125 // enqueue/remove a command while this one is processed
126 vlc_mutex_unlock( &m_lock );
128 // Execute the command
129 cCommand.get()->execute();
133 vlc_mutex_unlock( &m_lock );
140 void AsyncQueue::CmdFlush::execute()