1 // Copyright 2010 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/message_loop/message_pump.h" 6 7 #include "base/check.h" 8 #include "base/message_loop/message_pump_default.h" 9 #include "base/message_loop/message_pump_for_io.h" 10 #include "base/message_loop/message_pump_for_ui.h" 11 #include "base/notreached.h" 12 #include "base/task/task_features.h" 13 #include "build/build_config.h" 14 15 #if BUILDFLAG(IS_APPLE) 16 #include "base/message_loop/message_pump_apple.h" 17 #endif 18 19 namespace base { 20 21 namespace { 22 23 std::atomic_bool g_align_wake_ups = false; 24 #if BUILDFLAG(IS_WIN) 25 bool g_explicit_high_resolution_timer_win = true; 26 #endif // BUILDFLAG(IS_WIN) 27 28 MessagePump::MessagePumpFactory* message_pump_for_ui_factory_ = nullptr; 29 30 } // namespace 31 32 MessagePump::MessagePump() = default; 33 34 MessagePump::~MessagePump() = default; 35 36 // static OverrideMessagePumpForUIFactory(MessagePumpFactory * factory)37void MessagePump::OverrideMessagePumpForUIFactory(MessagePumpFactory* factory) { 38 DCHECK(!message_pump_for_ui_factory_); 39 message_pump_for_ui_factory_ = factory; 40 } 41 42 // static IsMessagePumpForUIFactoryOveridden()43bool MessagePump::IsMessagePumpForUIFactoryOveridden() { 44 return message_pump_for_ui_factory_ != nullptr; 45 } 46 47 // static Create(MessagePumpType type)48std::unique_ptr<MessagePump> MessagePump::Create(MessagePumpType type) { 49 switch (type) { 50 case MessagePumpType::UI: 51 if (message_pump_for_ui_factory_) 52 return message_pump_for_ui_factory_(); 53 #if BUILDFLAG(IS_APPLE) 54 return message_pump_apple::Create(); 55 #elif BUILDFLAG(IS_NACL) || BUILDFLAG(IS_AIX) 56 // Currently NaCl and AIX don't have a UI MessagePump. 57 // TODO(abarth): Figure out if we need this. 58 NOTREACHED(); 59 return nullptr; 60 #else 61 return std::make_unique<MessagePumpForUI>(); 62 #endif 63 64 case MessagePumpType::IO: 65 return std::make_unique<MessagePumpForIO>(); 66 67 #if BUILDFLAG(IS_ANDROID) 68 case MessagePumpType::JAVA: 69 return std::make_unique<MessagePumpForUI>(); 70 #endif 71 72 #if BUILDFLAG(IS_APPLE) 73 case MessagePumpType::NS_RUNLOOP: 74 return std::make_unique<MessagePumpNSRunLoop>(); 75 #endif 76 77 case MessagePumpType::CUSTOM: 78 NOTREACHED(); 79 return nullptr; 80 81 case MessagePumpType::DEFAULT: 82 #if BUILDFLAG(IS_IOS) 83 // On iOS, a native runloop is always required to pump system work. 84 return std::make_unique<MessagePumpCFRunLoop>(); 85 #else 86 return std::make_unique<MessagePumpDefault>(); 87 #endif 88 } 89 } 90 91 // static InitializeFeatures()92void MessagePump::InitializeFeatures() { 93 g_align_wake_ups = FeatureList::IsEnabled(kAlignWakeUps); 94 #if BUILDFLAG(IS_WIN) 95 g_explicit_high_resolution_timer_win = 96 FeatureList::IsEnabled(kExplicitHighResolutionTimerWin); 97 #endif 98 } 99 AdjustDelayedRunTime(TimeTicks earliest_time,TimeTicks run_time,TimeTicks latest_time)100TimeTicks MessagePump::AdjustDelayedRunTime(TimeTicks earliest_time, 101 TimeTicks run_time, 102 TimeTicks latest_time) { 103 // Windows relies on the low resolution timer rather than manual wake up 104 // alignment. 105 #if BUILDFLAG(IS_WIN) 106 if (g_explicit_high_resolution_timer_win) { 107 return earliest_time; 108 } 109 #else // BUILDFLAG(IS_WIN) 110 if (g_align_wake_ups.load(std::memory_order_relaxed)) { 111 TimeTicks aligned_run_time = earliest_time.SnappedToNextTick( 112 TimeTicks(), GetTaskLeewayForCurrentThread()); 113 return std::min(aligned_run_time, latest_time); 114 } 115 #endif 116 return run_time; 117 } 118 119 } // namespace base 120