• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)37 void MessagePump::OverrideMessagePumpForUIFactory(MessagePumpFactory* factory) {
38   DCHECK(!message_pump_for_ui_factory_);
39   message_pump_for_ui_factory_ = factory;
40 }
41 
42 // static
IsMessagePumpForUIFactoryOveridden()43 bool MessagePump::IsMessagePumpForUIFactoryOveridden() {
44   return message_pump_for_ui_factory_ != nullptr;
45 }
46 
47 // static
Create(MessagePumpType type)48 std::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()92 void 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)100 TimeTicks 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