Пример #1
0
static void BackgroundWorkerCancel( struct background_worker* worker, void* id)
{
    vlc_mutex_lock( &worker->lock );
    for( size_t i = 0; i < vlc_array_count( &worker->tail.data ); )
    {
        struct bg_queued_item* item =
            vlc_array_item_at_index( &worker->tail.data, i );

        if( id == NULL || item->id == id )
        {
            vlc_array_remove( &worker->tail.data, i );
            worker->conf.pf_release( item->entity );
            free( item );
            continue;
        }

        ++i;
    }

    while( ( id == NULL && worker->head.active )
        || ( id != NULL && worker->head.id == id ) )
    {
        worker->head.deadline = VLC_TS_0;
        vlc_cond_signal( &worker->head.worker_wait );
        vlc_cond_signal( &worker->tail.wait );
        vlc_cond_wait( &worker->head.wait, &worker->lock );
    }
    vlc_mutex_unlock( &worker->lock );
}
Пример #2
0
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 );
    }
}
Пример #3
0
Файл: dbus.c Проект: etix/vlc
static void remove_timeout(DBusTimeout *to, void *data)
{
    intf_thread_t *intf = data;
    intf_sys_t *sys = intf->p_sys;
    unsigned idx = vlc_array_index_of_item(sys->p_timeouts, to);

    vlc_mutex_lock(&sys->lock);
    vlc_array_remove(sys->p_timeouts, idx);
    vlc_mutex_unlock(&sys->lock);
}
Пример #4
0
Файл: dbus.c Проект: etix/vlc
static void remove_watch( DBusWatch *p_watch, void *p_data )
{
    intf_thread_t *p_intf = (intf_thread_t*) p_data;
    intf_sys_t    *p_sys  = (intf_sys_t*) p_intf->p_sys;

    vlc_mutex_lock( &p_sys->lock );

    vlc_array_remove( p_sys->p_watches,
                      vlc_array_index_of_item( p_sys->p_watches, p_watch ) );

    vlc_mutex_unlock( &p_sys->lock );
}
Пример #5
0
static void remove_timeout( DBusTimeout *p_timeout, void *p_data )
{
    intf_thread_t *p_intf = (intf_thread_t*) p_data;
    intf_sys_t    *p_sys  = (intf_sys_t*) p_intf->p_sys;

    vlc_mutex_lock( &p_sys->lock );

    vlc_array_remove( p_sys->p_timeouts,
                      vlc_array_index_of_item( p_sys->p_timeouts, p_timeout ) );

    vlc_mutex_unlock( &p_sys->lock );
}
Пример #6
0
Файл: event.c Проект: AsamQi/vlc
/**************************************************************************
 *       libvlc_event_detach (public) :
 *
 * Remove a callback for an event.
 **************************************************************************/
void libvlc_event_detach( libvlc_event_manager_t *p_event_manager,
                                     libvlc_event_type_t event_type,
                                     libvlc_callback_t pf_callback,
                                     void *p_user_data )
{
    libvlc_event_listeners_group_t * listeners_group;
    libvlc_event_listener_t * listener;
    int i, j;
    bool found = false;

    vlc_mutex_lock( &p_event_manager->event_sending_lock );
    vlc_mutex_lock( &p_event_manager->object_lock );
    for( i = 0; i < vlc_array_count(&p_event_manager->listeners_groups); i++)
    {
        listeners_group = vlc_array_item_at_index(&p_event_manager->listeners_groups, i);
        if( listeners_group->event_type == event_type )
        {
            for( j = 0; j < vlc_array_count(&listeners_group->listeners); j++)
            {
                listener = vlc_array_item_at_index(&listeners_group->listeners, j);
                if( listener->event_type == event_type &&
                    listener->pf_callback == pf_callback &&
                    listener->p_user_data == p_user_data )
                {
                    /* that's our listener */

                    /* Mark this group as edited so that libvlc_event_send
                     * will recheck what listener to call */
                    listeners_group->b_sublistener_removed = true;

                    free( listener );
                    vlc_array_remove( &listeners_group->listeners, j );
                    found = true;
                    break;
                }
            }
        }
    }
    vlc_mutex_unlock( &p_event_manager->object_lock );
    vlc_mutex_unlock( &p_event_manager->event_sending_lock );

    /* Now make sure any pending async event won't get fired after that point */
    libvlc_event_listener_t listener_to_remove;
    listener_to_remove.event_type  = event_type;
    listener_to_remove.pf_callback = pf_callback;
    listener_to_remove.p_user_data = p_user_data;
    listener_to_remove.is_asynchronous = true;

    libvlc_event_async_ensure_listener_removal(p_event_manager, &listener_to_remove);

    assert(found);
}
Пример #7
0
static fingerprint_request_t * GetResult( fingerprinter_thread_t *f )
{
    fingerprint_request_t *r = NULL;
    fingerprinter_sys_t *p_sys = f->p_sys;
    vlc_mutex_lock( &p_sys->results.lock );
    if ( vlc_array_count( &p_sys->results.queue ) )
    {
        r = vlc_array_item_at_index( &p_sys->results.queue, 0 );
        vlc_array_remove( &p_sys->results.queue, 0 );
    }
    vlc_mutex_unlock( &p_sys->results.lock );
    return r;
}
Пример #8
0
/**************************************************************************
 *       ml_item_removed  (private) (Callback from media_list_view)
 **************************************************************************/
static void
ml_item_removed( const libvlc_event_t * p_event, libvlc_media_list_view_t * p_mlv )
{
    libvlc_media_t * p_md = p_event->u.media_list_item_deleted.item;
    int i = vlc_array_index_of_item( &p_mlv->p_this_view_data->array, p_md );
    if( i >= 0 )
    {
        libvlc_media_list_view_will_delete_item( p_mlv, p_md, i );
        vlc_array_remove( &p_mlv->p_this_view_data->array, i );
        libvlc_media_list_view_item_deleted( p_mlv, p_md, i );
        libvlc_media_release( p_md );
    }
}
Пример #9
0
static void remove_watch( DBusWatch *p_watch, void *p_data )
{
    intf_thread_t *p_intf = (intf_thread_t*) p_data;
    intf_sys_t    *p_sys  = (intf_sys_t*) p_intf->p_sys;

    msg_Dbg( p_intf, "Removing dbus watch on fd %d",
              dbus_watch_get_unix_fd( p_watch ) );

    vlc_mutex_lock( &p_sys->lock );

    vlc_array_remove( p_sys->p_watches,
                      vlc_array_index_of_item( p_sys->p_watches, p_watch ) );

    vlc_mutex_unlock( &p_sys->lock );
}
Пример #10
0
static void
dialog_remove_locked(vlc_dialog_provider *p_provider, vlc_dialog_id *p_id)
{
    ssize_t i_idx = vlc_array_index_of_item(&p_provider->dialog_array, p_id);
    assert(i_idx >= 0);
    vlc_array_remove(&p_provider->dialog_array, i_idx);

    vlc_mutex_lock(&p_id->lock);
    p_id->i_refcount--;
    if (p_id->i_refcount == 0)
    {
        vlc_mutex_unlock(&p_id->lock);
        dialog_id_release(p_id);
    }
    else
        vlc_mutex_unlock(&p_id->lock);
}
Пример #11
0
bool vlc_http_cookies_store(vlc_http_cookie_jar_t *p_jar, const char *cookies,
                            bool secure, const char *host, const char *path)
{
    assert(host != NULL);
    assert(path != NULL);

    int i;

    http_cookie_t *cookie = cookie_parse(cookies, host, path);
    if (cookie == NULL)
        return false;
    if (!cookie_is_valid(cookie, secure, host, path))
    {
        cookie_destroy(cookie);
        return false;
    }

    vlc_mutex_lock( &p_jar->lock );

    for( i = 0; i < vlc_array_count( &p_jar->cookies ); i++ )
    {
        http_cookie_t *iter = vlc_array_item_at_index( &p_jar->cookies, i );

        assert( iter->psz_name );
        assert( iter->psz_domain );
        assert( iter->psz_path );

        bool domains_match =
            vlc_ascii_strcasecmp( cookie->psz_domain, iter->psz_domain ) == 0;
        bool paths_match = strcmp( cookie->psz_path, iter->psz_path ) == 0;
        bool names_match = strcmp( cookie->psz_name, iter->psz_name ) == 0;
        if( domains_match && paths_match && names_match )
        {
            /* Remove previous value for this cookie */
            vlc_array_remove( &p_jar->cookies, i );
            cookie_destroy(iter);
            break;
        }
    }
    vlc_array_append( &p_jar->cookies, cookie );

    vlc_mutex_unlock( &p_jar->lock );

    return true;
}
Пример #12
0
static void entry_item_remove( services_discovery_t *p_sd,
                               netbios_ns_entry *p_entry )
{
    services_discovery_sys_t *p_sys = p_sd->p_sys;

    for ( int i = 0; i < vlc_array_count( p_sys->p_entry_item_list ); i++ )
    {
        struct entry_item *p_entry_item;

        p_entry_item = vlc_array_item_at_index( p_sys->p_entry_item_list, i );
        if( p_entry_item->p_entry == p_entry  )
        {
            services_discovery_RemoveItem( p_sd, p_entry_item->p_item );
            vlc_gc_decref( p_entry_item->p_item );
            vlc_array_remove(  p_sys->p_entry_item_list, i );
            free( p_entry_item );
            break;
        }
    }
}
Пример #13
0
/* LibVLC internal version */
void _libvlc_media_list_remove_index( libvlc_media_list_t * p_mlist,
                                     int index,
                                     libvlc_exception_t * p_e )
{
    libvlc_media_t * p_md;

    if( index < 0 || index >= vlc_array_count( &p_mlist->items ))
    {
        libvlc_exception_raise( p_e, "Index out of bounds");
        return;
    }

    p_md = vlc_array_item_at_index( &p_mlist->items, index );

    notify_item_deletion( p_mlist, p_md, index, EventWillHappen );
    vlc_array_remove( &p_mlist->items, index );
    notify_item_deletion( p_mlist, p_md, index, EventDidHappen );

    libvlc_media_release( p_md );
}
Пример #14
0
/* LibVLC internal version */
int libvlc_media_list_internal_remove_index( libvlc_media_list_t * p_mlist,
                                             int index )
{
    libvlc_media_t * p_md;

    if( index < 0 || index >= vlc_array_count( &p_mlist->items ))
    {
        libvlc_printerr( "Index out of bounds" );
        return -1;
    }

    p_md = vlc_array_item_at_index( &p_mlist->items, index );

    notify_item_deletion( p_mlist, p_md, index, EventWillHappen );
    vlc_array_remove( &p_mlist->items, index );
    notify_item_deletion( p_mlist, p_md, index, EventDidHappen );

    libvlc_media_release( p_md );
    return 0;
}
Пример #15
0
/**************************************************************************
 *       libvlc_event_detach (public) :
 *
 * Remove a callback for an event.
 **************************************************************************/
void libvlc_event_detach(libvlc_event_manager_t *em, libvlc_event_type_t type,
                         libvlc_callback_t callback, void *opaque)
{
    vlc_mutex_lock(&em->lock);
    for (size_t i = 0; i < vlc_array_count(&em->listeners); i++)
    {
         libvlc_event_listener_t *listener;

         listener = vlc_array_item_at_index(&em->listeners, i);

         if (listener->event_type == type
          && listener->pf_callback == callback
          && listener->p_user_data == opaque)
         {   /* that's our listener */
             vlc_array_remove(&em->listeners, i);
             vlc_mutex_unlock(&em->lock);
             free(listener);
             return;
         }
    }
    abort();
}
Пример #16
0
static void Run          ( intf_thread_t *p_intf )
{
    intf_sys_t    *p_sys = p_intf->p_sys;
    mtime_t        i_last_run = mdate();

    for( ;; )
    {
        int canc = vlc_savecancel();
        vlc_mutex_lock( &p_sys->lock );

        int i_watches = vlc_array_count( p_sys->p_watches );
        struct pollfd *p_fds = calloc( i_watches, sizeof( struct pollfd ) );

        int i_fds = GetPollFds( p_intf, p_fds );

        mtime_t i_now = mdate(), i_loop_interval = i_now - i_last_run;

        msg_Dbg( p_intf,
                 "%lld µs elapsed since last wakeup",
                 (long long) i_loop_interval );

        int i_next_timeout = UpdateTimeouts( p_intf, i_loop_interval );
        i_last_run = i_now;

        vlc_mutex_unlock( &p_sys->lock );

        if( -1 != i_next_timeout )
            msg_Dbg( p_intf, "next timeout is in %d ms", i_next_timeout );
        msg_Dbg( p_intf, "Sleeping until something happens" );

        /* thread cancellation is allowed while the main loop sleeps */
        vlc_restorecancel( canc );

        int i_pollres = poll( p_fds, i_fds, i_next_timeout );
        int i_errsv   = errno;

        canc = vlc_savecancel();

        msg_Dbg( p_intf, "the main loop has been woken up" );

        if( -1 == i_pollres )
        { /* XXX: What should we do when poll() fails ? */
            char buf[64];
            msg_Err( p_intf, "poll() failed: %s", strerror_r( i_errsv, buf, 64 ) );
            free( p_fds ); p_fds = NULL;
            vlc_restorecancel( canc );
            continue;
        }

        /* Was the main loop woken up manually ? */
        if( 0 < i_pollres && ( p_fds[0].revents & POLLIN ) )
        {
            char buf;
            msg_Dbg( p_intf, "Removing a byte from the self-pipe" );
            (void)read( p_fds[0].fd, &buf, 1 );
        }

        /* We need to lock the mutex while building lists of events,
         * timeouts and watches to process but we can't keep the lock while
         * processing them, or 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 );

        /* Get the list of timeouts to process */
        unsigned int i_timeouts = vlc_array_count( p_sys->p_timeouts );
        DBusTimeout *p_timeouts[i_timeouts];
        for( unsigned int i = 0; i < i_timeouts; i++ )
        {
            p_timeouts[i] = vlc_array_item_at_index( p_sys->p_timeouts, i );
        }

        /* Get the list of watches to process */
        i_watches = vlc_array_count( p_sys->p_watches );
        DBusWatch *p_watches[i_watches];
        for( int i = 0; i < i_watches; i++ )
        {
            p_watches[i] = vlc_array_item_at_index( p_sys->p_watches, i );
        }

        /* Get the list of events to process */
        int i_events = vlc_array_count( p_intf->p_sys->p_events );
        callback_info_t* p_info[i_events];
        for( int i = i_events - 1; i >= 0; i-- )
        {
            p_info[i] = vlc_array_item_at_index( p_intf->p_sys->p_events, i );
            vlc_array_remove( p_intf->p_sys->p_events, i );
        }

        /* now we can release the lock and process what's pending */
        vlc_mutex_unlock( &p_intf->p_sys->lock );

        ProcessEvents( p_intf, p_info, i_events );
        ProcessWatches( p_intf, p_watches, i_watches, p_fds, i_fds );

        free( p_fds ); p_fds = NULL;

        ProcessTimeouts( p_intf, p_timeouts, i_timeouts );
        DispatchDBusMessages( p_intf );

        vlc_restorecancel( canc );
    }
}
Пример #17
0
static void* Thread( void* data )
{
    struct background_worker* worker = data;

    for( ;; )
    {
        struct bg_queued_item* item = NULL;
        void* handle;

        vlc_mutex_lock( &worker->lock );
        for( ;; )
        {
            if( vlc_array_count( &worker->tail.data ) )
            {
                item = vlc_array_item_at_index( &worker->tail.data, 0 );
                handle = NULL;

                vlc_array_remove( &worker->tail.data, 0 );
            }

            if( worker->head.deadline == VLC_TS_0 && item == NULL )
                worker->head.active = false;
            worker->head.id = item ? item->id : NULL;
            vlc_cond_broadcast( &worker->head.wait );

            if( item )
            {
                if( item->timeout > 0 )
                    worker->head.deadline = mdate() + item->timeout * 1000;
                else
                    worker->head.deadline = INT64_MAX;
            }
            else if( worker->head.deadline != VLC_TS_0 )
            {
                /* Wait 1 seconds for new inputs before terminating */
                mtime_t deadline = mdate() + INT64_C(1000000);
                int ret = vlc_cond_timedwait( &worker->tail.wait,
                                              &worker->lock, deadline );
                if( ret != 0 )
                {
                    /* Timeout: if there is still no items, the thread will be
                     * terminated at next loop iteration (active = false). */
                    worker->head.deadline = VLC_TS_0;
                }
                continue;
            }
            break;
        }

        if( !worker->head.active )
        {
            vlc_mutex_unlock( &worker->lock );
            break;
        }
        vlc_mutex_unlock( &worker->lock );

        assert( item != NULL );

        if( worker->conf.pf_start( worker->owner, item->entity, &handle ) )
        {
            worker->conf.pf_release( item->entity );
            free( item );
            continue;
        }

        for( ;; )
        {
            vlc_mutex_lock( &worker->lock );

            bool const b_timeout = worker->head.deadline <= mdate();
            worker->head.probe_request = false;

            vlc_mutex_unlock( &worker->lock );

            if( b_timeout ||
                worker->conf.pf_probe( worker->owner, handle ) )
            {
                worker->conf.pf_stop( worker->owner, handle );
                worker->conf.pf_release( item->entity );
                free( item );
                break;
            }

            vlc_mutex_lock( &worker->lock );
            if( worker->head.probe_request == false &&
                worker->head.deadline > mdate() )
            {
                vlc_cond_timedwait( &worker->head.worker_wait, &worker->lock,
                                     worker->head.deadline );
            }
            vlc_mutex_unlock( &worker->lock );
        }
    }

    return NULL;
}
Пример #18
0
Файл: dbus.c Проект: etix/vlc
static void *Run( void *data )
{
    intf_thread_t *p_intf = data;
    intf_sys_t    *p_sys = p_intf->p_sys;

    int canc = vlc_savecancel();

    for( ;; )
    {
        vlc_mutex_lock( &p_sys->lock );

        int i_watches = vlc_array_count( p_sys->p_watches );
        struct pollfd fds[i_watches];
        memset(fds, 0, sizeof fds);

        int i_fds = GetPollFds( p_intf, fds );
        int timeout = next_timeout(p_intf);

        vlc_mutex_unlock( &p_sys->lock );

        /* thread cancellation is allowed while the main loop sleeps */
        vlc_restorecancel( canc );

        while (poll(fds, i_fds, timeout) == -1)
        {
            if (errno != EINTR)
                goto error;
        }

        canc = vlc_savecancel();

        /* Was the main loop woken up manually ? */
        if (fds[0].revents & POLLIN)
        {
            char buf;
            (void)read( fds[0].fd, &buf, 1 );
        }

        /* We need to lock the mutex while building lists of events,
         * timeouts and watches to process but we can't keep the lock while
         * processing them, or 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 );

        process_timeouts(p_intf);

        /* Get the list of watches to process */
        i_watches = vlc_array_count( p_sys->p_watches );
        DBusWatch *p_watches[i_watches ? i_watches : 1];
        for( int i = 0; i < i_watches; i++ )
        {
            p_watches[i] = vlc_array_item_at_index( p_sys->p_watches, i );
        }

        /* Get the list of events to process */
        int i_events = vlc_array_count( p_intf->p_sys->p_events );
        callback_info_t* p_info[i_events ? i_events : 1];
        for( int i = i_events - 1; i >= 0; i-- )
        {
            p_info[i] = vlc_array_item_at_index( p_intf->p_sys->p_events, i );
            vlc_array_remove( p_intf->p_sys->p_events, i );
        }

        /* now we can release the lock and process what's pending */
        vlc_mutex_unlock( &p_intf->p_sys->lock );

        ProcessEvents( p_intf, p_info, i_events );
        ProcessWatches( p_intf, p_watches, i_watches, fds, i_fds );

        DispatchDBusMessages( p_intf );
    }
error:
    vlc_restorecancel(canc);
    return NULL;
}