[libbluray-devel] commit: Fixed hdmv interpreter deadlocks: (hpi1 )

git at videolan.org git at videolan.org
Thu Sep 2 12:37:24 CEST 2010


libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Thu Sep  2 13:27:19 2010 +0300| [228c63d16d36e92f04a8f6c741dd2a8112854851] | committer: hpi1 

Fixed hdmv interpreter deadlocks:
Added BD_MUTEX
 - renamed WIN32 pthread_* wrappers to bd_mutex_*
 - added pthread wrappers with error-checking and support for recursive locking
 - Use bd_mutex_* in register.c

> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=228c63d16d36e92f04a8f6c741dd2a8112854851
---

 src/libbluray/register.c |   10 ++--
 src/util/mutex.h         |  102 +++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 96 insertions(+), 16 deletions(-)

diff --git a/src/libbluray/register.c b/src/libbluray/register.c
index 52d979c..8d04dfb 100644
--- a/src/libbluray/register.c
+++ b/src/libbluray/register.c
@@ -149,7 +149,7 @@ struct bd_registers_s
     int          num_cb;
     PSR_CB_DATA *cb;
 
-    pthread_mutex_t mutex;
+    BD_MUTEX     mutex;
 };
 
 /*
@@ -162,7 +162,7 @@ BD_REGISTERS *bd_registers_init(void)
 
     memcpy(p->psr, bd_psr_init, sizeof(bd_psr_init));
 
-    pthread_mutex_init(&p->mutex, NULL);
+    bd_mutex_init(&p->mutex);
 
     return p;
 }
@@ -170,7 +170,7 @@ BD_REGISTERS *bd_registers_init(void)
 void bd_registers_free(BD_REGISTERS *p)
 {
     if (p) {
-        pthread_mutex_destroy(&p->mutex);
+        bd_mutex_destroy(&p->mutex);
 
         X_FREE(p->cb);
     }
@@ -184,12 +184,12 @@ void bd_registers_free(BD_REGISTERS *p)
 
 void bd_psr_lock(BD_REGISTERS *p)
 {
-    pthread_mutex_lock(&p->mutex);
+    bd_mutex_lock(&p->mutex);
 }
 
 void bd_psr_unlock(BD_REGISTERS *p)
 {
-    pthread_mutex_unlock(&p->mutex);
+    bd_mutex_unlock(&p->mutex);
 }
 
 /*
diff --git a/src/util/mutex.h b/src/util/mutex.h
index 0138f46..a242115 100644
--- a/src/util/mutex.h
+++ b/src/util/mutex.h
@@ -24,36 +24,116 @@
 #include "config.h"
 #endif
 
-#if defined(HAVE_PTHREAD_H)
-#   include <pthread.h>
-#elif defined(_WIN32)
+#if defined(_WIN32)
 #   include <windows.h>
+#elif defined(HAVE_PTHREAD_H)
+#   include <pthread.h>
 #else
 #   error no mutex support found
 #endif
 
-#if defined(_WIN32) && !defined(HAVE_PTHREAD_H)
+
+#if defined(_WIN32)
 
 #include <errno.h>
 
-typedef CRITICAL_SECTION pthread_mutex_t;
+typedef CRITICAL_SECTION BD_MUTEX;
 
-#define pthread_mutex_lock(m) \
+#define bd_mutex_lock(m) \
   (EnterCriticalSection(m), 0)
 
-#define pthread_mutex_unlock(m) \
+#define bd_mutex_unlock(m) \
   (LeaveCriticalSection(m), 0)
 
-#define pthread_mutex_trylock(m) \
+#define bd_mutex_trylock(m) \
   (TryEnterCriticalSection(m) ? 0 : EBUSY)
 
-#define pthread_mutex_init(m, a) \
+#define bd_mutex_init(m, a) \
   (InitializeCriticalSection(m), 0)
 
-#define pthread_mutex_destroy(m) \
+#define bd_mutex_destroy(m) \
   (DeleteCriticalSection(m), 0)
 
-#endif
+
+#elif defined(HAVE_PTHREAD_H)
+
+/*
+ * recursive mutex
+ */
+
+typedef struct bd_mutex_s BD_MUTEX;
+struct bd_mutex_s {
+    int             lock_count;
+    pthread_t       owner;
+    pthread_mutex_t mutex;
+};
+
+static inline int bd_mutex_init(BD_MUTEX *p)
+{
+    p->owner      = (pthread_t)-1;
+    p->lock_count = 0;
+
+    if (pthread_mutex_init(&p->mutex, NULL)) {
+        DEBUG(DBG_BLURAY|DBG_CRIT, "bd_mutex_init() failed !");
+        return -1;
+    }
+
+    return 0;
+}
+
+static inline int bd_mutex_destroy(BD_MUTEX *p)
+{
+    if (pthread_mutex_destroy(&p->mutex)) {
+        DEBUG(DBG_BLURAY|DBG_CRIT, "bd_mutex_destroy() failed !");
+        return -1;
+    }
+    return 0;
+}
+
+static int bd_mutex_lock(BD_MUTEX *p)
+{
+    if (pthread_equal(p->owner, pthread_self())) {
+        /* recursive lock */
+        p->lock_count++;
+        return 0;
+    }
+
+    if (pthread_mutex_lock(&p->mutex)) {
+        DEBUG(DBG_BLURAY|DBG_CRIT, "bd_mutex_lock() failed !");
+        return -1;
+    }
+
+    p->owner      = pthread_self();
+    p->lock_count = 1;
+
+    return 0;
+}
+
+static int bd_mutex_unlock(BD_MUTEX *p)
+{
+    if (!pthread_equal(p->owner, pthread_self())) {
+        DEBUG(DBG_BLURAY|DBG_CRIT, "bd_mutex_unlock(): not owner !");
+        return -1;
+    }
+
+    p->lock_count--;
+    if (p->lock_count > 0) {
+        return 0;
+    }
+
+    /* unlock */
+
+    p->owner = (pthread_t)-1;
+
+    if (pthread_mutex_unlock(&p->mutex)) {
+        DEBUG(DBG_BLURAY|DBG_CRIT, "bd_mutex_unlock() failed !");
+        return -1;
+    }
+
+    return 0;
+}
+
+#endif // HAVE_PTHREAD_H
 
 
 #endif // LIBBLURAY_MUTEX_H_



More information about the libbluray-devel mailing list