From d1a74a287ee1a84b90e5675904dac7f945cffca1 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 26 Mar 2015 19:59:08 +0000 Subject: [PATCH] re PR libstdc++/58038 (std::this_thread::sleep_until can cause inifinite sleep) PR libstdc++/58038 PR libstdc++/60421 * include/std/thread (this_thread::sleep_for): Check for negative durations. (this_thread::sleep_until): Check for times in the past. * testsuite/30_threads/this_thread/58038.cc: New. * testsuite/30_threads/this_thread/60421.cc: New. From-SVN: r221708 --- libstdc++-v3/ChangeLog | 10 +++++ libstdc++-v3/include/std/thread | 8 +++- .../testsuite/30_threads/this_thread/58038.cc | 44 +++++++++++++++++++ .../testsuite/30_threads/this_thread/60421.cc | 38 ++++++++++++++++ 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 libstdc++-v3/testsuite/30_threads/this_thread/58038.cc create mode 100644 libstdc++-v3/testsuite/30_threads/this_thread/60421.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 3021c74e381..cac4af869c1 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2015-03-26 Jonathan Wakely + + PR libstdc++/58038 + PR libstdc++/60421 + * include/std/thread (this_thread::sleep_for): Check for negative + durations. + (this_thread::sleep_until): Check for times in the past. + * testsuite/30_threads/this_thread/58038.cc: New. + * testsuite/30_threads/this_thread/60421.cc: New. + 2015-03-26 Jonathan Wakely PR libstdc++/62259 diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread index 2f9e69a88cd..ebbda62fa72 100644 --- a/libstdc++-v3/include/std/thread +++ b/libstdc++-v3/include/std/thread @@ -279,6 +279,8 @@ _GLIBCXX_END_NAMESPACE_VERSION inline void sleep_for(const chrono::duration<_Rep, _Period>& __rtime) { + if (__rtime <= __rtime.zero()) + return; auto __s = chrono::duration_cast(__rtime); auto __ns = chrono::duration_cast(__rtime - __s); #ifdef _GLIBCXX_USE_NANOSLEEP @@ -297,7 +299,11 @@ _GLIBCXX_END_NAMESPACE_VERSION template inline void sleep_until(const chrono::time_point<_Clock, _Duration>& __atime) - { sleep_for(__atime - _Clock::now()); } + { + auto __now = _Clock::now(); + if (__now < __atime) + sleep_for(__atime - __now); + } _GLIBCXX_END_NAMESPACE_VERSION } diff --git a/libstdc++-v3/testsuite/30_threads/this_thread/58038.cc b/libstdc++-v3/testsuite/30_threads/this_thread/58038.cc new file mode 100644 index 00000000000..afa861c60f2 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/this_thread/58038.cc @@ -0,0 +1,44 @@ +// Copyright (C) 2015 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++11" } +// { dg-require-cstdint "" } +// { dg-require-time "" } + +#include +#include + +void +test01() +{ + auto now = std::chrono::system_clock::now(); + std::this_thread::sleep_until(now - 1ul * std::chrono::seconds(1)); +} + +void +test02() +{ + auto now = std::chrono::steady_clock::now(); + std::this_thread::sleep_until(now - 1ul * std::chrono::seconds(1)); +} + +int +main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/30_threads/this_thread/60421.cc b/libstdc++-v3/testsuite/30_threads/this_thread/60421.cc new file mode 100644 index 00000000000..ecc4deb4a0f --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/this_thread/60421.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2015 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++11" } +// { dg-require-cstdint "" } +// { dg-require-time "" } + +#include +#include +#include + +void +test01() +{ + std::this_thread::sleep_for(std::chrono::seconds(0)); + std::this_thread::sleep_for(std::chrono::seconds(-1)); + std::this_thread::sleep_for(std::chrono::duration::zero()); +} + +int +main() +{ + test01(); +} -- 2.30.2