[vlc-devel] [PATCH 1/2] win32: implement non-recursive locks

Rémi Denis-Courmont remi at remlab.net
Tue Jun 7 09:28:11 CEST 2016


Le 2016-06-07 09:12, Steve Lhomme a écrit :
> locked & b_recursive are always accessed in the CriticalSection
>
> --
> replaces https://patches.videolan.org/patch/13622/ by reusing the
> locked value
> it needs to count the number of locks so that recursive unlocks don't
> consider
> it's unlocked the first time
>
> trylock doesn't assert on EBUSY, just like with pthread
> ---
>  include/vlc_threads.h | 12 +++++-------
>  src/win32/thread.c    | 27 +++++++++++++++++++++------
>  2 files changed, 26 insertions(+), 13 deletions(-)
>
> diff --git a/include/vlc_threads.h b/include/vlc_threads.h
> index 33b9b53..1fe22bf 100644
> --- a/include/vlc_threads.h
> +++ b/include/vlc_threads.h
> @@ -57,18 +57,16 @@ typedef struct vlc_thread *vlc_thread_t;
>  # define LIBVLC_NEED_SLEEP
>  typedef struct
>  {
> +    int locked;
> +    bool b_recursive;
>      bool dynamic;
>      union
>      {
> -        struct
> -        {
> -            bool locked;
> -            unsigned long contention;
> -        };
> -        CRITICAL_SECTION mutex;
> +        unsigned long contention; /* static */
> +        CRITICAL_SECTION mutex;   /* dynamic */
>      };
>  } vlc_mutex_t;
> -#define VLC_STATIC_MUTEX { false, { { false, 0 } } }
> +#define VLC_STATIC_MUTEX { 0, false, false, { 0 } }
>  #define LIBVLC_NEED_CONDVAR
>  #define LIBVLC_NEED_SEMAPHORE
>  #define LIBVLC_NEED_RWLOCK
> diff --git a/src/win32/thread.c b/src/win32/thread.c
> index 963a8d7..ce5ecd4 100644
> --- a/src/win32/thread.c
> +++ b/src/win32/thread.c
> @@ -69,15 +69,17 @@ struct vlc_thread
>  /*** Mutexes ***/
>  void vlc_mutex_init( vlc_mutex_t *p_mutex )
>  {
> -    /* This creates a recursive mutex. This is OK as fast mutexes 
> have
> -     * no defined behavior in case of recursive locking. */
>      InitializeCriticalSection (&p_mutex->mutex);
> +    p_mutex->locked = 0;
> +    p_mutex->b_recursive = false;
>      p_mutex->dynamic = true;
>  }
>
>  void vlc_mutex_init_recursive( vlc_mutex_t *p_mutex )
>  {
>      InitializeCriticalSection( &p_mutex->mutex );
> +    p_mutex->locked = 0;
> +    p_mutex->b_recursive = true;
>      p_mutex->dynamic = true;
>  }
>
> @@ -102,13 +104,15 @@ void vlc_mutex_lock (vlc_mutex_t *p_mutex)
>              vlc_cond_wait (&super_variable, &super_mutex);
>              p_mutex->contention--;
>          }
> -        p_mutex->locked = true;
> +        p_mutex->locked = 1;
>          vlc_mutex_unlock (&super_mutex);
>          vlc_restorecancel (canc);
>          return;
>      }
>
>      EnterCriticalSection (&p_mutex->mutex);
> +    assert(!p_mutex->locked || p_mutex->b_recursive);
> +    p_mutex->locked++;
>  }
>
>  int vlc_mutex_trylock (vlc_mutex_t *p_mutex)
> @@ -121,14 +125,23 @@ int vlc_mutex_trylock (vlc_mutex_t *p_mutex)
>          vlc_mutex_lock (&super_mutex);
>          if (!p_mutex->locked)
>          {
> -            p_mutex->locked = true;
> +            p_mutex->locked = 1;
>              ret = 0;
>          }
>          vlc_mutex_unlock (&super_mutex);
>          return ret;
>      }
>
> -    return TryEnterCriticalSection (&p_mutex->mutex) ? 0 : EBUSY;
> +    int ret = TryEnterCriticalSection (&p_mutex->mutex);
> +    if (ret == 0)
> +        return EBUSY;
> +
> +    assert(!p_mutex->locked || p_mutex->b_recursive);
> +    if (unlikely(p_mutex->locked && !p_mutex->b_recursive))
> +        return EDEADLK; /* we already had the non-recursive lock */

You can't both lock and return an error.

> +
> +    p_mutex->locked++;
> +    return 0;
>  }
>
>  void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
> @@ -139,13 +152,15 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
>
>          vlc_mutex_lock (&super_mutex);
>          assert (p_mutex->locked);
> -        p_mutex->locked = false;
> +        p_mutex->locked = 0;
>          if (p_mutex->contention)
>              vlc_cond_broadcast (&super_variable);
>          vlc_mutex_unlock (&super_mutex);
>          return;
>      }
>
> +    p_mutex->locked--;
> +    assert(p_mutex->locked >= 0);
>      LeaveCriticalSection (&p_mutex->mutex);
>  }

-- 
Rémi Denis-Courmont
http://www.remlab.net/


More information about the vlc-devel mailing list