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

Rémi Denis-Courmont remi at remlab.net
Fri Jun 24 04:49:01 CEST 2016


Le 2016-06-21 12:56, Steve Lhomme a écrit :
> locked & b_recursive are always accessed in the CriticalSection

It probably works, but I still don't see why you need a counter, 
insofar as you use a Win32 critical section. The recursion counter is 
already provided by Win32. AFAICT, a boolean is enough.

>
> --
> simple rebase of https://patches.videolan.org/patch/13641/
> ---
>  include/vlc_threads.h | 12 +++++-------
>  src/win32/thread.c    | 30 ++++++++++++++++++++++++------
>  2 files changed, 29 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 9eb3db7..8d53185 100644
> --- a/src/win32/thread.c
> +++ b/src/win32/thread.c
> @@ -96,15 +96,17 @@ static BOOL WINAPI
> SleepConditionVariableFallback(CONDITION_VARIABLE *cv,
>  /*** 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;
>  }
>
> @@ -126,12 +128,14 @@ void vlc_mutex_lock (vlc_mutex_t *p_mutex)
>              SleepConditionVariableCS(&super_variable, &super_mutex,
> INFINITE);
>              p_mutex->contention--;
>          }
> -        p_mutex->locked = true;
> +        p_mutex->locked = 1;
>          LeaveCriticalSection(&super_mutex);
>          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)
> @@ -143,14 +147,26 @@ int vlc_mutex_trylock (vlc_mutex_t *p_mutex)
>          EnterCriticalSection(&super_mutex);
>          if (!p_mutex->locked)
>          {
> -            p_mutex->locked = true;
> +            p_mutex->locked = 1;
>              ret = 0;
>          }
>          LeaveCriticalSection(&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))
> +    {
> +        LeaveCriticalSection (&p_mutex->mutex);
> +        return EDEADLK; /* we already had the non-recursive lock */
> +    }
> +
> +    p_mutex->locked++;
> +    return 0;
>  }
>
>  void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
> @@ -159,13 +175,15 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
>      {   /* static mutexes */
>          EnterCriticalSection(&super_mutex);
>          assert (p_mutex->locked);
> -        p_mutex->locked = false;
> +        p_mutex->locked = 0;
>          if (p_mutex->contention)
>              WakeAllConditionVariable(&super_variable);
>          LeaveCriticalSection(&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