[vlc-devel] [PATCH 1/2] Add vlc_mutex_trylock

Rémi Denis-Courmont remi at remlab.net
Tue Mar 10 21:46:57 CET 2009


---
 include/vlc_threads.h |    1 +
 src/libvlccore.sym    |    1 +
 src/misc/threads.c    |   43 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/include/vlc_threads.h b/include/vlc_threads.h
index e7acc8d..fcb22f4 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( bool, 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 49be4e6..2419796 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 8875d15..9f0bc40 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,48 @@ 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.
+ *
+ * <b>Beware</b>: 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 true if the mutex could be acquired, false if it was locked by
+ * another thread
+ */
+bool vlc_mutex_trylock (vlc_mutex_t *p_mutex)
+{
+#if defined(LIBVLC_USE_PTHREAD)
+    int val = pthread_mutex_trylock( p_mutex );
+
+    if (val == EBUSY)
+        return false;
+    VLC_THREAD_ASSERT ("locking mutex");
+    return true;
+
+#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);
+
+#endif
+}
 
 /**
  * Releases a mutex (or crashes if the mutex is not locked by the caller).
-- 
1.6.2




More information about the vlc-devel mailing list