Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3812)

Unified Diff: base/message_loop/message_pump_mac_unittest.cc

Issue 2709813003: [Mac] Reduce timer CPU use in MessagePumpCFRunLoopBase. (Closed)
Patch Set: Fix iOS compile problems. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/message_loop/message_pump_mac.mm ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/message_loop/message_pump_mac_unittest.cc
diff --git a/base/message_loop/message_pump_mac_unittest.cc b/base/message_loop/message_pump_mac_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..17c70c8a6cbe32e577a10c035d87d74fb9e5aadf
--- /dev/null
+++ b/base/message_loop/message_pump_mac_unittest.cc
@@ -0,0 +1,108 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/message_loop/message_pump_mac.h"
+
+#include "base/mac/scoped_cftyperef.h"
+#include "base/macros.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+class TestMessagePumpCFRunLoopBase {
+ public:
+ bool TestCanInvalidateTimers() {
+ return MessagePumpCFRunLoopBase::CanInvalidateCFRunLoopTimers();
+ }
+ static void SetTimerValid(CFRunLoopTimerRef timer, bool valid) {
+ MessagePumpCFRunLoopBase::ChromeCFRunLoopTimerSetValid(timer, valid);
+ }
+
+ static void PerformTimerCallback(CFRunLoopTimerRef timer, void* info) {
+ TestMessagePumpCFRunLoopBase* self =
+ static_cast<TestMessagePumpCFRunLoopBase*>(info);
+ self->timer_callback_called_ = true;
+
+ if (self->invalidate_timer_in_callback_) {
+ SetTimerValid(timer, false);
+ }
+ }
+
+ bool invalidate_timer_in_callback_;
+
+ bool timer_callback_called_;
+};
+
+TEST(MessagePumpMacTest, TestCanInvalidateTimers) {
+ TestMessagePumpCFRunLoopBase message_pump_test;
+
+ // Catch whether or not the use of private API ever starts failing.
+ EXPECT_TRUE(message_pump_test.TestCanInvalidateTimers());
+}
+
+TEST(MessagePumpMacTest, TestInvalidatedTimerReuse) {
+ TestMessagePumpCFRunLoopBase message_pump_test;
+
+ CFRunLoopTimerContext timer_context = CFRunLoopTimerContext();
+ timer_context.info = &message_pump_test;
+ const CFTimeInterval kCFTimeIntervalMax =
+ std::numeric_limits<CFTimeInterval>::max();
+ ScopedCFTypeRef<CFRunLoopTimerRef> test_timer(CFRunLoopTimerCreate(
+ NULL, // allocator
+ kCFTimeIntervalMax, // fire time
+ kCFTimeIntervalMax, // interval
+ 0, // flags
+ 0, // priority
+ TestMessagePumpCFRunLoopBase::PerformTimerCallback, &timer_context));
+ CFRunLoopAddTimer(CFRunLoopGetCurrent(), test_timer,
+ kMessageLoopExclusiveRunLoopMode);
+
+ // Sanity check.
+ EXPECT_TRUE(CFRunLoopTimerIsValid(test_timer));
+
+ // Confirm that the timer fires as expected, and that it's not a one-time-use
+ // timer (those timers are invalidated after they fire).
+ CFAbsoluteTime next_fire_time = CFAbsoluteTimeGetCurrent() + 0.01;
+ CFRunLoopTimerSetNextFireDate(test_timer, next_fire_time);
+ message_pump_test.timer_callback_called_ = false;
+ message_pump_test.invalidate_timer_in_callback_ = false;
+ CFRunLoopRunInMode(kMessageLoopExclusiveRunLoopMode, 0.02, true);
+ EXPECT_TRUE(message_pump_test.timer_callback_called_);
+ EXPECT_TRUE(CFRunLoopTimerIsValid(test_timer));
+
+ // As a repeating timer, the timer should have a new fire date set in the
+ // future.
+ EXPECT_GT(CFRunLoopTimerGetNextFireDate(test_timer), next_fire_time);
+
+ // Try firing the timer, and invalidating it within its callback.
+ next_fire_time = CFAbsoluteTimeGetCurrent() + 0.01;
+ CFRunLoopTimerSetNextFireDate(test_timer, next_fire_time);
+ message_pump_test.timer_callback_called_ = false;
+ message_pump_test.invalidate_timer_in_callback_ = true;
+ CFRunLoopRunInMode(kMessageLoopExclusiveRunLoopMode, 0.02, true);
+ EXPECT_TRUE(message_pump_test.timer_callback_called_);
+ EXPECT_FALSE(CFRunLoopTimerIsValid(test_timer));
+
+ // The CFRunLoop believes the timer is invalid, so it should not have a
+ // fire date.
+ EXPECT_EQ(0, CFRunLoopTimerGetNextFireDate(test_timer));
+
+ // Now mark the timer as valid and confirm that it still fires correctly.
+ TestMessagePumpCFRunLoopBase::SetTimerValid(test_timer, true);
+ EXPECT_TRUE(CFRunLoopTimerIsValid(test_timer));
+ next_fire_time = CFAbsoluteTimeGetCurrent() + 0.01;
+ CFRunLoopTimerSetNextFireDate(test_timer, next_fire_time);
+ message_pump_test.timer_callback_called_ = false;
+ message_pump_test.invalidate_timer_in_callback_ = false;
+ CFRunLoopRunInMode(kMessageLoopExclusiveRunLoopMode, 0.02, true);
+ EXPECT_TRUE(message_pump_test.timer_callback_called_);
+ EXPECT_TRUE(CFRunLoopTimerIsValid(test_timer));
+
+ // Confirm that the run loop again gave it a new fire date in the future.
+ EXPECT_GT(CFRunLoopTimerGetNextFireDate(test_timer), next_fire_time);
+
+ CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), test_timer,
+ kMessageLoopExclusiveRunLoopMode);
+}
+} // namespace base
« no previous file with comments | « base/message_loop/message_pump_mac.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698