cec: use a recursive mutex
[deb_libcec.git] / src / lib / platform / threads.cpp
index 31a0fb31571e4c3d49c6e077bf56d155b18d8748..9ea0008e713f81065aed63d85194e24eafad79a0 100644 (file)
@@ -37,7 +37,7 @@ using namespace CEC;
 
 CMutex::CMutex(void)
 {
-  pthread_mutex_init(&m_mutex, NULL);
+  pthread_mutex_init(&m_mutex, GetMutexAttribute());
 }
 
 CMutex::~CMutex(void)
@@ -60,6 +60,19 @@ void CMutex::Unlock(void)
   pthread_mutex_unlock(&m_mutex);
 }
 
+static pthread_mutexattr_t g_mutexAttr;
+pthread_mutexattr_t *CMutex::GetMutexAttribute()
+{
+  static bool bAttributeInitialised = false;
+  if (!bAttributeInitialised)
+  {
+    pthread_mutexattr_init(&g_mutexAttr);
+    pthread_mutexattr_settype(&g_mutexAttr, PTHREAD_MUTEX_RECURSIVE);
+    bAttributeInitialised = true;
+  }
+  return &g_mutexAttr;
+}
+
 CLockObject::CLockObject(CMutex *mutex, bool bTryLock /* = false */) :
   m_mutex(mutex)
 {
@@ -175,10 +188,17 @@ void *CThread::ThreadHandler(CThread *thread)
 
   if (thread)
   {
+    CLockObject lock(&thread->m_threadMutex);
     thread->m_bRunning = true;
+    lock.Leave();
     thread->m_threadCondition.Broadcast();
+
     retVal = thread->Process();
+
+    lock.Lock();
     thread->m_bRunning = false;
+    lock.Leave();
+    thread->m_threadCondition.Broadcast();
   }
 
   return retVal;