xineplayer and vdr-xine-plugin

  • Frage an Euch von Reinhard (aus der ML):


    Hi,


    while facing deadlocks in xine I've written an emulation of an recursive
    mutex, as xine cannot use non posix extensions to be portable.


    The code below seems to work but are there any errors left?
    What happens if the thread owning the lock is cancelled?


    Feel free to send me your improvements. Thanks!


    /*
    * xine_rmutex - xine's recursive mutex emulation
    */


    struct xine_rmutex_s {
    pthread_mutex_t access_rmutex;
    pthread_cond_t unlock_cond;
    int lock_count;
    pthread_t lock_owner;
    };


    typedef struct xine_rmutex_s xine_rmutex_t;


    int _x_rmutex_init(xine_rmutex_t *rmutex);
    int _x_rmutex_lock(xine_rmutex_t *rmutex);
    int _x_rmutex_timedlock(xine_rmutex_t *rmutex, int ms_to_time_out);
    int _x_rmutex_unlock(xine_rmutex_t *rmutex);
    int _x_rmutex_destroy(xine_rmutex_t *rmutex);


    #include "assert.h"


    int _x_rmutex_init(xine_rmutex_t *rmutex)
    {
    pthread_mutex_init(&rmutex->access_rmutex, 0);
    pthread_cond_init(&rmutex->unlock_cond, 0);
    rmutex->lock_count = 0;


    return 0;
    }


    int _x_rmutex_lock(xine_rmutex_t *rmutex)
    {
    return _x_rmutex_timedlock(rmutex, -1);
    }


    int _x_rmutex_timedlock(xine_rmutex_t *rmutex, int ms_to_time_out)
    {
    int r = 0;


    struct timespec abstime;
    {
    struct timeval now;
    gettimeofday(&now, 0);


    abstime.tv_sec = now.tv_sec + ms_to_time_out / 1000;
    abstime.tv_nsec = now.tv_usec * 1000 + (ms_to_time_out % 1000) * 1e6;


    if (abstime.tv_nsec > 1e9)
    {
    abstime.tv_nsec -= 1e9;
    abstime.tv_sec++;
    }
    }


    pthread_mutex_lock(&rmutex->access_rmutex);


    assert(rmutex->lock_count >= 0);


    while (0 == r
    && rmutex->lock_count > 0
    && !pthread_equal(rmutex->lock_owner, pthread_self()))
    {
    if (ms_to_time_out < 0)
    pthread_cond_wait(&rmutex->unlock_cond, &rmutex->access_rmutex);
    else
    r = pthread_cond_timedwait(&rmutex->unlock_cond,
    &rmutex->access_rmutex, &abstime);
    }


    if (0 == r)
    {
    rmutex->lock_owner = pthread_self();
    rmutex->lock_count++;
    }


    pthread_mutex_unlock(&rmutex->access_rmutex);


    return r;
    }


    int _x_rmutex_unlock(xine_rmutex_t *rmutex)
    {
    int r = 0;


    pthread_mutex_lock(&rmutex->access_rmutex);


    assert(rmutex->lock_count > 0);
    assert(pthread_equal(rmutex->lock_owner, pthread_self()));


    rmutex->lock_count--;


    if (rmutex->lock_count == 0)
    pthread_cond_broadcast(&rmutex->unlock_cond);


    pthread_mutex_unlock(&rmutex->access_rmutex);


    return r;
    }


    int _x_rmutex_destroy(xine_rmutex_t *rmutex)
    {
    pthread_cond_destroy(&rmutex->unlock_cond);
    pthread_mutex_destroy(&rmutex->access_rmutex);


    return 0;
    }


    Bye.
    --
    Dipl.-Inform. (FH) Reinhard Nissl
    mailto:rnissl at gmx.de

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!