diff options
Diffstat (limited to 'src/corelib/thread')
-rw-r--r-- | src/corelib/thread/qmutex.cpp | 4 | ||||
-rw-r--r-- | src/corelib/thread/qmutex.h | 38 |
2 files changed, 32 insertions, 10 deletions
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index 6e0fa4eedb..0aee4aeda4 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -275,7 +275,7 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT Attempts to lock the mutex. This function returns \c true if the lock was obtained; otherwise it returns \c false. If another thread has - locked the mutex, this function will wait for at most \a duration + locked the mutex, this function will wait for at least \a duration for the mutex to become available. Note: Passing a negative duration as the \a duration is equivalent to @@ -299,7 +299,7 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT Attempts to lock the mutex. This function returns \c true if the lock was obtained; otherwise it returns \c false. If another thread has - locked the mutex, this function will wait at most until \a timePoint + locked the mutex, this function will wait at least until \a timePoint for the mutex to become available. Note: Passing a \a timePoint which has already passed is equivalent diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h index 3a0e22e3bd..056ebdeaa5 100644 --- a/src/corelib/thread/qmutex.h +++ b/src/corelib/thread/qmutex.h @@ -46,8 +46,11 @@ #if QT_HAS_INCLUDE(<chrono>) # include <chrono> +# include <limits> #endif +class tst_QMutex; + QT_BEGIN_NAMESPACE @@ -135,14 +138,7 @@ public: template <class Rep, class Period> bool try_lock_for(std::chrono::duration<Rep, Period> duration) { - // N4606 § 30.4.1.3 [thread.timedmutex.requirements]/5 specifies that - // a duration less than or equal to duration.zero() shall result in a - // try_lock, unlike QMutex's tryLock with a negative duration which - // results in a lock. - - if (duration <= duration.zero()) - return tryLock(0); - return tryLock(std::chrono::duration_cast<std::chrono::milliseconds>(duration).count()); + return tryLock(convertToMilliseconds(duration)); } // TimedLockable concept @@ -162,6 +158,32 @@ public: private: Q_DISABLE_COPY(QMutex) friend class QMutexLocker; + friend class ::tst_QMutex; + +#if QT_HAS_INCLUDE(<chrono>) + template<class Rep, class Period> + static int convertToMilliseconds(std::chrono::duration<Rep, Period> duration) + { + // N4606 § 30.4.1.3.5 [thread.timedmutex.requirements] specifies that a + // duration less than or equal to duration.zero() shall result in a + // try_lock, unlike QMutex's tryLock with a negative duration which + // results in a lock. + + if (duration <= duration.zero()) + return 0; + + // when converting from 'duration' to milliseconds, make sure that + // the result is not shorter than 'duration': + std::chrono::milliseconds wait = std::chrono::duration_cast<std::chrono::milliseconds>(duration); + if (wait < duration) + wait += std::chrono::milliseconds(1); + Q_ASSERT(wait >= duration); + const auto ms = wait.count(); + const auto maxInt = (std::numeric_limits<int>::max)(); + + return ms < maxInt ? int(ms) : maxInt; + } +#endif }; class Q_CORE_EXPORT QMutexLocker |