/***************************************************************************** * StateChange: callback on input "state" *****************************************************************************/ static int StateChange( intf_thread_t *p_intf ) { intf_sys_t *p_sys = p_intf->p_sys; playlist_t *p_playlist = p_sys->p_playlist; input_thread_t *p_input; input_item_t *p_item; if( p_intf->p_sys->b_dead ) return VLC_SUCCESS; UpdateCaps( p_intf ); if( !p_sys->b_meta_read && p_sys->i_playing_state == 0) { p_input = playlist_CurrentInput( p_playlist ); if( p_input ) { p_item = input_GetItem( p_input ); if( p_item ) { p_sys->b_meta_read = true; TrackChangeEmit( p_intf, p_item ); } vlc_object_release( p_input ); } } StatusChangeEmit( p_intf ); return VLC_SUCCESS; }
/** * ProcessEvents() reacts to a list of events originating from other VLC threads * * This function must be called with p_sys->lock unlocked * * @param intf_thread_t *p_intf This interface thread state * @param callback_info_t *p_events the list of events to process */ static void ProcessEvents( intf_thread_t *p_intf, callback_info_t **p_events, int i_events ) { for( int i = 0; i < i_events; i++ ) { switch( p_events[i]->signal ) { case SIGNAL_ITEM_CURRENT: TrackChange( p_intf ); break; case SIGNAL_INTF_CHANGE: case SIGNAL_PLAYLIST_ITEM_APPEND: case SIGNAL_PLAYLIST_ITEM_DELETED: TrackListChangeEmit( p_intf, p_events[i]->signal, p_events[i]->i_node ); break; case SIGNAL_RANDOM: case SIGNAL_REPEAT: case SIGNAL_LOOP: StatusChangeEmit( p_intf ); break; case SIGNAL_STATE: StateChange( p_intf ); break; case SIGNAL_INPUT_METADATA: break; default: assert(0); } free( p_events[i] ); } }
static void Run ( intf_thread_t *p_intf ) { for( ;; ) { if( dbus_connection_get_dispatch_status(p_intf->p_sys->p_conn) == DBUS_DISPATCH_COMPLETE ) msleep( INTF_IDLE_SLEEP ); int canc = vlc_savecancel(); dbus_connection_read_write_dispatch( p_intf->p_sys->p_conn, 0 ); /* Get the list of events to process * * We can't keep the lock on p_intf->p_sys->p_events, else we risk a * deadlock: * The signal functions could lock mutex X while p_events is locked; * While some other function in vlc (playlist) might lock mutex X * and then set a variable which would call AllCallback(), which itself * needs to lock p_events to add a new event. */ vlc_mutex_lock( &p_intf->p_sys->lock ); int i_events = vlc_array_count( p_intf->p_sys->p_events ); callback_info_t* info[i_events]; for( int i = i_events - 1; i >= 0; i-- ) { info[i] = vlc_array_item_at_index( p_intf->p_sys->p_events, i ); vlc_array_remove( p_intf->p_sys->p_events, i ); } vlc_mutex_unlock( &p_intf->p_sys->lock ); for( int i = 0; i < i_events; i++ ) { switch( info[i]->signal ) { case SIGNAL_ITEM_CURRENT: TrackChange( p_intf ); break; case SIGNAL_INTF_CHANGE: case SIGNAL_PLAYLIST_ITEM_APPEND: case SIGNAL_PLAYLIST_ITEM_DELETED: TrackListChangeEmit( p_intf, info[i]->signal, info[i]->i_node ); break; case SIGNAL_RANDOM: case SIGNAL_REPEAT: case SIGNAL_LOOP: StatusChangeEmit( p_intf ); break; case SIGNAL_STATE: StateChange( p_intf, info[i]->i_input_state ); break; default: assert(0); } free( info[i] ); } vlc_restorecancel( canc ); } }