+wxConditionInternal::wxConditionInternal()
+{
+    m_wasSignaled = FALSE;
+    m_nWaiters = 0;
+
+    if ( pthread_cond_init(&m_condition, (pthread_condattr_t *)NULL) != 0 )
+    {
+        // this is supposed to never happen
+        wxFAIL_MSG( _T("pthread_cond_init() failed") );
+    }
+
+    if ( pthread_mutex_init(&m_mutex, (pthread_mutexattr_t *)NULL) != 0 ||
+         pthread_mutex_init(&m_mutexProtect, NULL) != 0 )
+    {
+        // neither this
+        wxFAIL_MSG( _T("wxCondition: pthread_mutex_init() failed") );
+    }
+
+    // initially the mutex is locked, so no thread can Signal() or Broadcast()
+    // until another thread starts to Wait()
+    if ( pthread_mutex_lock(&m_mutex) != 0 )
+    {
+        wxFAIL_MSG( _T("wxCondition: pthread_mutex_lock() failed") );
+    }
+}
+
+wxConditionInternal::~wxConditionInternal()
+{
+    if ( pthread_cond_destroy( &m_condition ) != 0 )
+    {
+        wxLogDebug(_T("Failed to destroy condition variable (some "
+                      "threads are probably still waiting on it?)"));
+    }
+
+    if ( pthread_mutex_unlock( &m_mutex ) != 0 )
+    {
+        wxLogDebug(_T("wxCondition: failed to unlock the mutex"));
+    }
+
+    if ( pthread_mutex_destroy( &m_mutex ) != 0 ||
+         pthread_mutex_destroy( &m_mutexProtect ) != 0 )
+    {
+        wxLogDebug(_T("Failed to destroy mutex (it is probably locked)"));
+    }
+}
+
+void wxConditionInternal::WaitDone()
+{
+    MutexLock lock(m_mutexProtect);
+
+    m_wasSignaled = FALSE;
+    m_nWaiters--;
+}
+
+bool wxConditionInternal::ShouldWait()
+{
+    MutexLock lock(m_mutexProtect);
+
+    if ( m_wasSignaled )
+    {
+        // the condition was signaled before we started to wait, reset the
+        // flag and return
+        m_wasSignaled = FALSE;
+
+        return FALSE;
+    }
+
+    // we start to wait for it
+    m_nWaiters++;
+
+    return TRUE;
+}
+
+bool wxConditionInternal::HasWaiters()
+{
+    MutexLock lock(m_mutexProtect);
+
+    if ( m_nWaiters )
+    {
+        // someone waits for us, signal the condition normally
+        return TRUE;
+    }
+
+    // nobody waits for us and may be never will - so just remember that the
+    // condition was signaled and don't do anything else
+    m_wasSignaled = TRUE;
+
+    return FALSE;
+}
+
+void wxConditionInternal::Wait()
+{
+    if ( ShouldWait() )
+    {
+        if ( pthread_cond_wait( &m_condition, &m_mutex ) != 0 )
+        {
+            // not supposed to ever happen
+            wxFAIL_MSG( _T("pthread_cond_wait() failed") );
+        }
+    }
+
+    WaitDone();
+}
+
+bool wxConditionInternal::WaitWithTimeout(const timespec* ts)
+{
+    bool ok;
+
+    if ( ShouldWait() )
+    {
+        switch ( pthread_cond_timedwait( &m_condition, &m_mutex, ts ) )
+        {
+            case 0:
+                // condition signaled
+                ok = TRUE;
+                break;
+
+            default:
+                wxLogDebug(_T("pthread_cond_timedwait() failed"));
+
+                // fall through
+
+            case ETIMEDOUT:
+            case EINTR:
+                // wait interrupted or timeout elapsed
+                ok = FALSE;
+        }
+    }
+    else
+    {
+        // the condition had already been signaled before
+        ok = TRUE;
+    }
+
+    WaitDone();
+
+    return ok;
+}
+
+void wxConditionInternal::Signal()
+{
+    if ( HasWaiters() )
+    {
+        MutexLock lock(m_mutex);
+
+        if ( pthread_cond_signal( &m_condition ) != 0 )
+        {
+            // shouldn't ever happen
+            wxFAIL_MSG(_T("pthread_cond_signal() failed"));
+        }
+    }
+}
+
+void wxConditionInternal::Broadcast()
+{
+    if ( HasWaiters() )
+    {
+        MutexLock lock(m_mutex);
+
+        if ( pthread_cond_broadcast( &m_condition ) != 0 )
+        {
+            // shouldn't ever happen
+            wxFAIL_MSG(_T("pthread_cond_broadcast() failed"));
+        }
+    }
+}
+