summaryrefslogtreecommitdiffstats
path: root/libcxx/include/thread
diff options
context:
space:
mode:
authorHoward Hinnant <hhinnant@apple.com>2012-08-30 19:14:33 +0000
committerHoward Hinnant <hhinnant@apple.com>2012-08-30 19:14:33 +0000
commitaad745a024a3d0fd573ac9649d4c659e6a713702 (patch)
tree4202c4d244881948d97301997eaefdc04a26fbf8 /libcxx/include/thread
parentb7188a2d008f87d0880997fbfedf6e932734d6df (diff)
downloadbcm5719-llvm-aad745a024a3d0fd573ac9649d4c659e6a713702.tar.gz
bcm5719-llvm-aad745a024a3d0fd573ac9649d4c659e6a713702.zip
Change sleep_for, sleep_until, and the condition_variable timed wait
functions to protect against duration and time_point overflow. Since we're about to wait anyway, we can afford to spend a few more cycles on this checking. I purposefully did not treat the timed try_locks with overflow checking. This fixes http://llvm.org/bugs/show_bug.cgi?id=13721 . I'm unsure if the standard needs clarification in this area, or if this is simply QOI. The <chrono> facilities were never intended to overflow check, but just to not overflow if durations stayed within +/- 292 years. llvm-svn: 162925
Diffstat (limited to 'libcxx/include/thread')
-rw-r--r--libcxx/include/thread18
1 files changed, 14 insertions, 4 deletions
diff --git a/libcxx/include/thread b/libcxx/include/thread
index d81e8537888..94e7ab6c54c 100644
--- a/libcxx/include/thread
+++ b/libcxx/include/thread
@@ -410,10 +410,20 @@ void
sleep_for(const chrono::duration<_Rep, _Period>& __d)
{
using namespace chrono;
- nanoseconds __ns = duration_cast<nanoseconds>(__d);
- if (__ns < __d)
- ++__ns;
- sleep_for(__ns);
+ if (__d > duration<_Rep, _Period>::zero())
+ {
+ _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
+ nanoseconds __ns;
+ if (__d < _Max)
+ {
+ __ns = duration_cast<nanoseconds>(__d);
+ if (__ns < __d)
+ ++__ns;
+ }
+ else
+ __ns = nanoseconds::max();
+ sleep_for(__ns);
+ }
}
template <class _Clock, class _Duration>
OpenPOWER on IntegriCloud