diff options
author | Tom Cherry <tomcherry@google.com> | 2017-03-24 16:52:29 -0700 |
---|---|---|
committer | Tom Cherry <tomcherry@google.com> | 2017-03-27 18:05:58 -0700 |
commit | 3d5729402ed14093cfc5385aa4cc67ce90b9b780 (patch) | |
tree | 35f3e934679d6b2d4bf5a20ab51aaeb859001c20 /base/properties_test.cpp | |
parent | b15429c0eade8a5f9b456c5f0aa57eec697e9ff2 (diff) | |
download | system_core-3d5729402ed14093cfc5385aa4cc67ce90b9b780.tar.gz system_core-3d5729402ed14093cfc5385aa4cc67ce90b9b780.tar.bz2 system_core-3d5729402ed14093cfc5385aa4cc67ce90b9b780.zip |
Fix timeouts for android::base::WaitForProperty*
std::chrono doesn't handle integer overflow, so using
std::chrono::milliseconds::max() to indicate an infinite timeout is
not handled well in the current code. It causes an 'absolute_timeout'
earlier in time than 'now' and causes the associated WaitForProperty*
functions to return immediately.
Also, any duration_cast from relative_timeout to nanoseconds would
cause the same issue, as it would overflow in the conversion and
result in an invalid results.
This change prevents any duration_casts of relative_timeout to
nanoseconds and replaces the logic to wait on an absolute timeout with
logic that compares the time elapsed to the provided relative timeout.
This change also includes a test that std::chrono::milliseconds::max()
does not return immediately and that negative values do return immediately.
Test: Boot bullhead + libbase_test
Change-Id: I335bfa7ba71e86c20119a0ed46014cad44361162
Diffstat (limited to 'base/properties_test.cpp')
-rw-r--r-- | base/properties_test.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/base/properties_test.cpp b/base/properties_test.cpp index 1bbe48249..de5f3dcfa 100644 --- a/base/properties_test.cpp +++ b/base/properties_test.cpp @@ -151,6 +151,38 @@ TEST(properties, WaitForProperty_timeout) { ASSERT_LT(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 600ms); } +TEST(properties, WaitForProperty_MaxTimeout) { + std::atomic<bool> flag{false}; + std::thread thread([&]() { + android::base::SetProperty("debug.libbase.WaitForProperty_test", "a"); + while (!flag) std::this_thread::yield(); + std::this_thread::sleep_for(500ms); + android::base::SetProperty("debug.libbase.WaitForProperty_test", "b"); + }); + + ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a", 1s)); + flag = true; + // Test that this does not immediately return false due to overflow issues with the timeout. + ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b")); + thread.join(); +} + +TEST(properties, WaitForProperty_NegativeTimeout) { + std::atomic<bool> flag{false}; + std::thread thread([&]() { + android::base::SetProperty("debug.libbase.WaitForProperty_test", "a"); + while (!flag) std::this_thread::yield(); + std::this_thread::sleep_for(500ms); + android::base::SetProperty("debug.libbase.WaitForProperty_test", "b"); + }); + + ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a", 1s)); + flag = true; + // Assert that this immediately returns with a negative timeout + ASSERT_FALSE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b", -100ms)); + thread.join(); +} + TEST(properties, WaitForPropertyCreation) { std::thread thread([&]() { std::this_thread::sleep_for(100ms); |