]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/include/std/shared_mutex
libstdc++: Fix try_lock_until and try_lock_shared_until on arbitrary clock
[thirdparty/gcc.git] / libstdc++-v3 / include / std / shared_mutex
index cfe2ec078e1d1527b7a8b603c68a48d86664d0d8..f6cf7e759675d5da72f753a33c13300449b5dbd3 100644 (file)
@@ -554,9 +554,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       bool
       try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
       {
+       // The user-supplied clock may not tick at the same rate as
+       // steady_clock, so we must loop in order to guarantee that
+       // the timeout has expired before returning false.
        typename _Clock::time_point __now = _Clock::now();
-       auto __rtime = __atime - __now;
-       return try_lock_for(__rtime);
+       do {
+           auto __rtime = __atime - __now;
+           if (try_lock_for(__rtime))
+             return true;
+           __now = _Clock::now();
+       } while (__atime > __now);
+       return false;
       }
 
     // Shared ownership
@@ -631,9 +639,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       try_lock_shared_until(const chrono::time_point<_Clock,
                                                     _Duration>& __atime)
       {
+       // The user-supplied clock may not tick at the same rate as
+       // steady_clock, so we must loop in order to guarantee that
+       // the timeout has expired before returning false.
        typename _Clock::time_point __now = _Clock::now();
-       auto __rtime = __atime - __now;
-       return try_lock_shared_for(__rtime);
+       do {
+           auto __rtime = __atime - __now;
+           if (try_lock_shared_for(__rtime))
+             return true;
+           __now = _Clock::now();
+       } while (__atime > __now);
+       return false;
       }
 
 #else // ! (_GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK)