Index: base/message_loop/message_loop.cc |
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc |
index eb0f968849485ea73ef8a1aab9094bb9527af403..f0c0803810d7247d16a398489338057e8dde0584 100644 |
--- a/base/message_loop/message_loop.cc |
+++ b/base/message_loop/message_loop.cc |
@@ -100,10 +100,26 @@ MessagePumpForIO* ToPumpIO(MessagePump* pump) { |
} |
#endif // !defined(OS_NACL_SFI) |
+MessageLoop::Type GetMessageLoopType(const MessageLoop::InitOptions& options) { |
+ if (options.message_pump_factory.is_null()) |
+ return options.message_loop_type; |
+ return MessageLoop::TYPE_CUSTOM; |
+} |
+ |
} // namespace |
//------------------------------------------------------------------------------ |
+MessageLoop::InitOptions::InitOptions() |
+ : message_loop_type(MessageLoop::TYPE_DEFAULT), |
+ timer_slack(TIMER_SLACK_NONE) { |
+} |
+ |
+MessageLoop::InitOptions::~InitOptions() { |
+} |
+ |
+//------------------------------------------------------------------------------ |
+ |
MessageLoop::TaskObserver::TaskObserver() { |
} |
@@ -115,6 +131,24 @@ MessageLoop::DestructionObserver::~DestructionObserver() { |
//------------------------------------------------------------------------------ |
+MessageLoop::MessageLoop(const InitOptions& options) |
+ : type_(GetMessageLoopType(options)), |
+#if defined(OS_WIN) |
+ pending_high_res_tasks_(0), |
+ in_high_res_mode_(false), |
+#endif |
+ nestable_tasks_allowed_(true), |
+#if defined(OS_WIN) |
+ os_modal_loop_(false), |
+#endif // OS_WIN |
+ init_options_(new InitOptions(options)), |
+ message_histogram_(NULL), |
+ run_loop_(NULL), |
+ incoming_task_queue_(new internal::IncomingTaskQueue(this)), |
+ message_loop_proxy_( |
+ new internal::MessageLoopProxyImpl(incoming_task_queue_)) { |
+} |
+ |
MessageLoop::MessageLoop(Type type) |
: type_(type), |
#if defined(OS_WIN) |
@@ -126,9 +160,11 @@ MessageLoop::MessageLoop(Type type) |
os_modal_loop_(false), |
#endif // OS_WIN |
message_histogram_(NULL), |
- run_loop_(NULL) { |
+ run_loop_(NULL), |
+ incoming_task_queue_(new internal::IncomingTaskQueue(this)), |
+ message_loop_proxy_( |
+ new internal::MessageLoopProxyImpl(incoming_task_queue_)) { |
Init(); |
- |
pump_ = CreateMessagePumpForType(type).Pass(); |
} |
@@ -144,12 +180,25 @@ MessageLoop::MessageLoop(scoped_ptr<MessagePump> pump) |
os_modal_loop_(false), |
#endif // OS_WIN |
message_histogram_(NULL), |
- run_loop_(NULL) { |
+ run_loop_(NULL), |
+ incoming_task_queue_(new internal::IncomingTaskQueue(this)), |
+ message_loop_proxy_( |
+ new internal::MessageLoopProxyImpl(incoming_task_queue_)) { |
DCHECK(pump_.get()); |
Init(); |
} |
MessageLoop::~MessageLoop() { |
+ if (init_options_) { |
+ // This message loop is destructed before we call Init. |
+ DCHECK(current() == NULL); |
+ DCHECK(incoming_task_queue_->empty()); |
+ DCHECK(!pump_); |
+ DCHECK(!destruction_observers_.might_have_observers()); |
+ incoming_task_queue_->WillDestroyCurrentMessageLoop(); |
+ return; |
+ } |
+ |
DCHECK_EQ(this, current()); |
// iOS just attaches to the loop, it doesn't Run it. |
@@ -260,6 +309,26 @@ scoped_ptr<MessagePump> MessageLoop::CreateMessagePumpForType(Type type) { |
return MESSAGE_PUMP_DEFAULT; |
} |
+void MessageLoop::Init() { |
+ if (init_options_) { |
+ DCHECK(!pump_); |
+ if (!init_options_->message_pump_factory.is_null()) |
+ pump_ = init_options_->message_pump_factory.Run(); |
+ else |
+ pump_ = CreateMessagePumpForType(init_options_->message_loop_type); |
+ SetTimerSlack(init_options_->timer_slack); |
+ init_options_.reset(); |
+ } |
+ |
+ DCHECK(!current()) << "should only have one message loop per thread"; |
+ lazy_tls_ptr.Pointer()->Set(this); |
+ |
+ incoming_task_queue_->StartScheduling(); |
+ message_loop_proxy_->Init(); |
+ thread_task_runner_handle_.reset( |
+ new ThreadTaskRunnerHandle(message_loop_proxy_)); |
+} |
+ |
void MessageLoop::AddDestructionObserver( |
DestructionObserver* destruction_observer) { |
DCHECK_EQ(this, current()); |
@@ -299,11 +368,13 @@ void MessageLoop::PostNonNestableDelayedTask( |
} |
void MessageLoop::Run() { |
+ DCHECK(!init_options_); |
RunLoop run_loop; |
run_loop.Run(); |
} |
void MessageLoop::RunUntilIdle() { |
+ DCHECK(!init_options_); |
RunLoop run_loop; |
run_loop.RunUntilIdle(); |
} |
@@ -383,15 +454,8 @@ bool MessageLoop::IsIdleForTesting() { |
//------------------------------------------------------------------------------ |
-void MessageLoop::Init() { |
- DCHECK(!current()) << "should only have one message loop per thread"; |
- lazy_tls_ptr.Pointer()->Set(this); |
- |
- incoming_task_queue_ = new internal::IncomingTaskQueue(this); |
- message_loop_proxy_ = |
- new internal::MessageLoopProxyImpl(incoming_task_queue_); |
- thread_task_runner_handle_.reset( |
- new ThreadTaskRunnerHandle(message_loop_proxy_)); |
+void MessageLoop::ScheduleWork() { |
+ pump_->ScheduleWork(); |
} |
void MessageLoop::RunHandler() { |
@@ -512,10 +576,6 @@ void MessageLoop::ReloadWorkQueue() { |
} |
} |
-void MessageLoop::ScheduleWork() { |
- pump_->ScheduleWork(); |
-} |
- |
//------------------------------------------------------------------------------ |
// Method and data for histogramming events and actions taken by each instance |
// on each thread. |