X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/85bf679acc597e76c9de47b9c6dab002c3cb7a6e..8e190f0ed9c242e6df5fd4dd99fdaf6c9dea1cda:/src/unix/threadpsx.cpp diff --git a/src/unix/threadpsx.cpp b/src/unix/threadpsx.cpp index 983ac3632a..5d7c3bcd2a 100644 --- a/src/unix/threadpsx.cpp +++ b/src/unix/threadpsx.cpp @@ -163,11 +163,16 @@ public: ~wxMutexInternal(); wxMutexError Lock(); + wxMutexError Lock(unsigned long ms); wxMutexError TryLock(); wxMutexError Unlock(); bool IsOk() const { return m_isOk; } +private: + // convert the result of pthread_mutex_[timed]lock() call to wx return code + wxMutexError HandleLockResult(int err); + private: pthread_mutex_t m_mutex; bool m_isOk; @@ -245,7 +250,61 @@ wxMutexInternal::~wxMutexInternal() wxMutexError wxMutexInternal::Lock() { - int err = pthread_mutex_lock(&m_mutex); + return HandleLockResult(pthread_mutex_lock(&m_mutex)); +} + +wxMutexError wxMutexInternal::Lock(unsigned long ms) +{ +#ifdef HAVE_PTHREAD_MUTEX_TIMEDLOCK + static const long MSEC_IN_SEC = 1000; + static const long NSEC_IN_MSEC = 1000000; + static const long NSEC_IN_USEC = 1000; + static const long NSEC_IN_SEC = MSEC_IN_SEC * NSEC_IN_MSEC; + + time_t seconds = ms/MSEC_IN_SEC; + long nanoseconds = (ms % MSEC_IN_SEC) * NSEC_IN_MSEC; + timespec ts = { 0, 0 }; + + // normally we should use clock_gettime(CLOCK_REALTIME) here but this + // function is in librt and we don't link with it currently, so use + // gettimeofday() instead -- if it turns out that this is really too + // imprecise, we should modify configure to check if clock_gettime() is + // available and whether it requires -lrt and use it instead +#if 0 + if ( clock_gettime(CLOCK_REALTIME, &ts) == 0 ) + { + } +#else + struct timeval tv; + if ( wxGetTimeOfDay(&tv) != -1 ) + { + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec*NSEC_IN_USEC; + } +#endif + else // fall back on system timer + { + ts.tv_sec = time(NULL); + } + + ts.tv_sec += seconds; + ts.tv_nsec += nanoseconds; + if ( ts.tv_nsec > NSEC_IN_SEC ) + { + ts.tv_sec += 1; + ts.tv_nsec -= NSEC_IN_SEC; + } + + return HandleLockResult(pthread_mutex_timedlock(&m_mutex, &ts)); +#else // !HAVE_PTHREAD_MUTEX_TIMEDLOCK + wxUnusedVar(ms); + + return wxMUTEX_MISC_ERROR; +#endif // HAVE_PTHREAD_MUTEX_TIMEDLOCK/!HAVE_PTHREAD_MUTEX_TIMEDLOCK +} + +wxMutexError wxMutexInternal::HandleLockResult(int err) +{ switch ( err ) { case EDEADLK: @@ -255,19 +314,23 @@ wxMutexError wxMutexInternal::Lock() return wxMUTEX_DEAD_LOCK; case EINVAL: - wxLogDebug(_T("pthread_mutex_lock(): mutex not initialized.")); + wxLogDebug(_T("pthread_mutex_[timed]lock(): mutex not initialized")); break; + case ETIMEDOUT: + return wxMUTEX_TIMEOUT; + case 0: return wxMUTEX_NO_ERROR; default: - wxLogApiError(_T("pthread_mutex_lock()"), err); + wxLogApiError(_T("pthread_mutex_[timed]lock()"), err); } return wxMUTEX_MISC_ERROR; } + wxMutexError wxMutexInternal::TryLock() { int err = pthread_mutex_trylock(&m_mutex);