From 05c63003294ccd8ef8b8b25524e713b1a0de9752 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 22 Oct 2015 15:54:27 +0800 Subject: [PATCH] Don't discard tasks in BridgeTaskRunner --- atom/browser/atom_browser_main_parts.cc | 1 + atom/browser/bridge_task_runner.cc | 32 +++++++++++++++++++++---- atom/browser/bridge_task_runner.h | 13 +++++++++- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index dfbdf4477fb..5fae5bfdbed 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -105,6 +105,7 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() { 1000)); brightray::BrowserMainParts::PreMainMessageLoopRun(); + BridgeTaskRunner::MessageLoopIsReady(); #if defined(USE_X11) libgtk2ui::GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); diff --git a/atom/browser/bridge_task_runner.cc b/atom/browser/bridge_task_runner.cc index 24572f3990d..882a3050de4 100644 --- a/atom/browser/bridge_task_runner.cc +++ b/atom/browser/bridge_task_runner.cc @@ -8,13 +8,33 @@ namespace atom { +// static +std::vector BridgeTaskRunner::tasks_; +std::vector BridgeTaskRunner::non_nestable_tasks_; + +// static +void BridgeTaskRunner::MessageLoopIsReady() { + auto message_loop = base::MessageLoop::current(); + CHECK(message_loop); + for (const TaskPair& task : tasks_) { + message_loop->task_runner()->PostDelayedTask( + base::get<0>(task), base::get<1>(task), base::get<2>(task)); + } + for (const TaskPair& task : non_nestable_tasks_) { + message_loop->task_runner()->PostNonNestableDelayedTask( + base::get<0>(task), base::get<1>(task), base::get<2>(task)); + } +} + bool BridgeTaskRunner::PostDelayedTask( const tracked_objects::Location& from_here, const base::Closure& task, base::TimeDelta delay) { auto message_loop = base::MessageLoop::current(); - if (!message_loop) - return false; + if (!message_loop) { + tasks_.push_back(base::MakeTuple(from_here, task, delay)); + return true; + } return message_loop->task_runner()->PostDelayedTask(from_here, task, delay); } @@ -22,7 +42,7 @@ bool BridgeTaskRunner::PostDelayedTask( bool BridgeTaskRunner::RunsTasksOnCurrentThread() const { auto message_loop = base::MessageLoop::current(); if (!message_loop) - return false; + return true; return message_loop->task_runner()->RunsTasksOnCurrentThread(); } @@ -32,8 +52,10 @@ bool BridgeTaskRunner::PostNonNestableDelayedTask( const base::Closure& task, base::TimeDelta delay) { auto message_loop = base::MessageLoop::current(); - if (!message_loop) - return false; + if (!message_loop) { + non_nestable_tasks_.push_back(base::MakeTuple(from_here, task, delay)); + return true; + } return message_loop->task_runner()->PostNonNestableDelayedTask( from_here, task, delay); diff --git a/atom/browser/bridge_task_runner.h b/atom/browser/bridge_task_runner.h index fb42aa3852f..12508f009d1 100644 --- a/atom/browser/bridge_task_runner.h +++ b/atom/browser/bridge_task_runner.h @@ -5,17 +5,23 @@ #ifndef ATOM_BROWSER_BRIDGE_TASK_RUNNER_H_ #define ATOM_BROWSER_BRIDGE_TASK_RUNNER_H_ +#include + #include "base/single_thread_task_runner.h" +#include "base/tuple.h" namespace atom { // Post all tasks to the current message loop's task runner if available, -// otherwise fail silently. +// otherwise delay the work until message loop is ready. class BridgeTaskRunner : public base::SingleThreadTaskRunner { public: BridgeTaskRunner() {} ~BridgeTaskRunner() override {} + // Called when message loop is ready. + static void MessageLoopIsReady(); + // base::SingleThreadTaskRunner: bool PostDelayedTask(const tracked_objects::Location& from_here, const base::Closure& task, @@ -27,6 +33,11 @@ class BridgeTaskRunner : public base::SingleThreadTaskRunner { base::TimeDelta delay) override; private: + using TaskPair = base::Tuple< + tracked_objects::Location, base::Closure, base::TimeDelta>; + static std::vector tasks_; + static std::vector non_nestable_tasks_; + DISALLOW_COPY_AND_ASSIGN(BridgeTaskRunner); };