@@ -24,6 +24,7 @@
#include <future>
#include <testsuite_hooks.h>
+#include <sys/time.h>
using namespace std;
@@ -154,6 +155,71 @@ void test_pr68519()
VERIFY( elapsed_steady >= std::chrono::seconds(1) );
}
+void perturb_system_clock(const std::chrono::seconds &seconds)
+{
+ struct timeval tv;
+ if (gettimeofday(&tv, NULL))
+ abort();
+
+ tv.tv_sec += seconds.count();
+ if (settimeofday(&tv, NULL))
+ abort();
+}
+
+// Ensure that advancing CLOCK_REALTIME doesn't make any difference
+// when we're waiting on std::chrono::steady_clock.
+void test05()
+{
+ auto const start = chrono::steady_clock::now();
+ future<void> f1 = async(launch::async, []() {
+ std::this_thread::sleep_for(std::chrono::seconds(10));
+ });
+
+ perturb_system_clock(chrono::seconds(20));
+
+ std::future_status status;
+ status = f1.wait_for(std::chrono::seconds(4));
+ VERIFY( status == std::future_status::timeout );
+
+ status = f1.wait_until(start + std::chrono::seconds(6));
+ VERIFY( status == std::future_status::timeout );
+
+ status = f1.wait_until(start + std::chrono::seconds(12));
+ VERIFY( status == std::future_status::ready );
+
+ auto const elapsed = chrono::steady_clock::now() - start;
+ VERIFY( elapsed >= std::chrono::seconds(10) );
+ VERIFY( elapsed < std::chrono::seconds(15) );
+
+ perturb_system_clock(chrono::seconds(-20));
+}
+
+// Ensure that advancing CLOCK_REALTIME does make a difference when
+// we're waiting on std::chrono::system_clock.
+void test06()
+{
+ auto const start = chrono::system_clock::now();
+ auto const start_steady = chrono::steady_clock::now();
+
+ future<void> f1 = async(launch::async, []() {
+ std::this_thread::sleep_for(std::chrono::seconds(5));
+ perturb_system_clock(chrono::seconds(60));
+ std::this_thread::sleep_for(std::chrono::seconds(5));
+ });
+ future_status status;
+ status = f1.wait_until(start + std::chrono::seconds(60));
+ VERIFY( status == std::future_status::timeout );
+
+ auto const elapsed_steady = chrono::steady_clock::now() - start_steady;
+ VERIFY( elapsed_steady >= std::chrono::seconds(5) );
+ VERIFY( elapsed_steady < std::chrono::seconds(10) );
+
+ status = f1.wait_until(start + std::chrono::seconds(75));
+ VERIFY( status == std::future_status::ready );
+
+ perturb_system_clock(chrono::seconds(-60));
+}
+
int main()
{
test01();
@@ -163,5 +229,9 @@ int main()
test03<slow_clock>();
test04();
test_pr68519();
+ if (geteuid() == 0) {
+ test05();
+ test06();
+ }
return 0;
}