From 685ac18a9a9d87646eda24a5550399fb5bc5f9fb Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Denis-Courmont?= Date: Tue, 10 Mar 2009 22:43:54 +0200 Subject: [PATCH] Add vlc_mutex_trylock --- include/vlc_threads.h | 1 + src/libvlccore.sym | 1 + src/misc/threads.c | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/include/vlc_threads.h b/include/vlc_threads.h index e7acc8d704..6a6bacada2 100644 --- a/include/vlc_threads.h +++ b/include/vlc_threads.h @@ -143,6 +143,7 @@ VLC_EXPORT( int, vlc_mutex_init, ( vlc_mutex_t * ) ); VLC_EXPORT( int, vlc_mutex_init_recursive, ( vlc_mutex_t * ) ); VLC_EXPORT( void, vlc_mutex_destroy, ( vlc_mutex_t * ) ); VLC_EXPORT( void, vlc_mutex_lock, ( vlc_mutex_t * ) ); +VLC_EXPORT( int, vlc_mutex_trylock, ( vlc_mutex_t * ) ); VLC_EXPORT( void, vlc_mutex_unlock, ( vlc_mutex_t * ) ); VLC_EXPORT( int, vlc_cond_init, ( vlc_cond_t * ) ); VLC_EXPORT( void, vlc_cond_destroy, ( vlc_cond_t * ) ); diff --git a/src/libvlccore.sym b/src/libvlccore.sym index 49be4e6c0b..2419796a56 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -458,6 +458,7 @@ vlc_mutex_destroy vlc_mutex_init vlc_mutex_init_recursive vlc_mutex_lock +vlc_mutex_trylock vlc_mutex_unlock __vlc_object_attach __vlc_object_create diff --git a/src/misc/threads.c b/src/misc/threads.c index 8875d15932..1b2f25eefa 100644 --- a/src/misc/threads.c +++ b/src/misc/threads.c @@ -356,6 +356,7 @@ void vlc_mutex_destroy (vlc_mutex_t *p_mutex) * Acquires a mutex. If needed, waits for any other thread to release it. * Beware of deadlocks when locking multiple mutexes at the same time, * or when using mutexes from callbacks. + * This function is not a cancellation-point. * * @param p_mutex mutex initialized with vlc_mutex_init() or * vlc_mutex_init_recursive() @@ -383,6 +384,46 @@ void vlc_mutex_lock (vlc_mutex_t *p_mutex) #endif } +/** + * Acquires a mutex if and only if it is not currently held by another thread. + * This function never sleeps and can be used in delay-critical code paths. + * This function is not a cancellation-point. + * + * Beware: If this function fails, then the mutex is held... by another + * thread. The calling thread must deal with the error appropriately. That + * typically implies postponing the operations that would have required the + * mutex. If the thread cannot defer those operations, then it must use + * vlc_mutex_lock(). If in doubt, use vlc_mutex_lock() instead. + * + * @param p_mutex mutex initialized with vlc_mutex_init() or + * vlc_mutex_init_recursive() + * @return 0 if the mutex could be acquired, an error code otherwise. + */ +int vlc_mutex_trylock (vlc_mutex_t *p_mutex) +{ +#if defined(LIBVLC_USE_PTHREAD) + int val = pthread_mutex_trylock( p_mutex ); + + if (val != EBUSY) + VLC_THREAD_ASSERT ("locking mutex"); + return val; + +#elif defined( WIN32 ) + if (InterlockedCompareExchange (&p_mutex->initialized, 0, 0) == 0) + { /* ^^ We could also lock super_mutex all the time... sluggish */ + assert (p_mutex != &super_mutex); /* this one cannot be static */ + + vlc_mutex_lock (&super_mutex); + if (InterlockedCompareExchange (&p_mutex->initialized, 0, 0) == 0) + vlc_mutex_init (p_mutex); + /* FIXME: destroy the mutex some time... */ + vlc_mutex_unlock (&super_mutex); + } + assert (InterlockedExchange (&p_mutex->initialized, 1) == 1); + return TryEnterCriticalSection (&p_mutex->mutex) ? 0 : EBUSY; + +#endif +} /** * Releases a mutex (or crashes if the mutex is not locked by the caller). -- 2.39.2