[vlc-devel] commit: Add vlc_mutex_trylock ( Rémi Denis-Courmont )

git version control git at videolan.org
Wed Mar 11 20:55:50 CET 2009


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Mar 10 22:43:54 2009 +0200| [685ac18a9a9d87646eda24a5550399fb5bc5f9fb] | committer: Rémi Denis-Courmont 

Add vlc_mutex_trylock

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=685ac18a9a9d87646eda24a5550399fb5bc5f9fb
---

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

diff --git a/include/vlc_threads.h b/include/vlc_threads.h
index e7acc8d..6a6baca 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 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..1b2f25e 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.
+ *
+ * <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 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).




More information about the vlc-devel mailing list