summaryrefslogtreecommitdiffstats
path: root/base/message_loop/incoming_task_queue.h
diff options
context:
space:
mode:
authorkinuko <kinuko@chromium.org>2015-05-23 04:38:37 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-23 11:39:08 +0000
commit7f68f8735355c1c73557c3cfb294b441901fc31d (patch)
tree85ae14ede9dc2d3df2d88d38ddeab43b7e4fb42e /base/message_loop/incoming_task_queue.h
parentb955d50ef7c0598baecc34ec7c4247c95e7819e5 (diff)
downloadchromium_src-7f68f8735355c1c73557c3cfb294b441901fc31d.zip
chromium_src-7f68f8735355c1c73557c3cfb294b441901fc31d.tar.gz
chromium_src-7f68f8735355c1c73557c3cfb294b441901fc31d.tar.bz2
Reland (3rd try): Lazily initialize MessageLoop for faster thread startup
Original review: https://codereview.chromium.org/1011683002/ 2nd try: https://codereview.chromium.org/1129953004/ 2nd try reverted due to race reports on Linux: https://crbug.com/489263 Data races on valid_thread_id_ after r330329 This fixes: - Race in MessageLoopProxyImpl by introducing lock - Race in BrowserMainLoop/BrowserThreadImpl, where BrowserThread::CurrentlyOn() called on one of BrowserThreads tries to touch other thread's message_loop() via global thread table. Reg: the latter race, the code flow that causes this race is like following: // On the main thread, we create all known browser threads: for (...) { { AutoLock lock(g_lock); g_threads[id] = new BrowserProcessSubThread(); } // [A] This initializes the thread's message_loop, which causes a race // against [B] in the new code because new threads can start running // immediately. thread->StartWithOptions(); } // On the new thread's main function, it calls CurrentlyOn() which does: { // [B] This touches other thread's Thread::message_loop. AutoLock lock(g_lock); return g_threads[other_thread_id] && g_threads[other_thread_id]->message_loop() == MessageLoop::current(); } This was safe before because both message_loop initialization and the first call to CurrentlyOn() on the new thread was done synchronously in StartWithOptions() while the main thread was blocked. In the new code new threads can start accessing message_loop() asynchronously while the main thread's for loop is running. PS1 is the original patch (2nd try) that got reverted. BUG=465458, 489263 Review URL: https://codereview.chromium.org/1131513007 Cr-Commit-Position: refs/heads/master@{#331235}
Diffstat (limited to 'base/message_loop/incoming_task_queue.h')
-rw-r--r--base/message_loop/incoming_task_queue.h10
1 files changed, 10 insertions, 0 deletions
diff --git a/base/message_loop/incoming_task_queue.h b/base/message_loop/incoming_task_queue.h
index 72e1f30..7dd1e82 100644
--- a/base/message_loop/incoming_task_queue.h
+++ b/base/message_loop/incoming_task_queue.h
@@ -53,6 +53,10 @@ class BASE_EXPORT IncomingTaskQueue
// Disconnects |this| from the parent message loop.
void WillDestroyCurrentMessageLoop();
+ // This should be called when the message loop becomes ready for
+ // scheduling work.
+ void StartScheduling();
+
private:
friend class RefCountedThreadSafe<IncomingTaskQueue>;
virtual ~IncomingTaskQueue();
@@ -66,6 +70,9 @@ class BASE_EXPORT IncomingTaskQueue
// does not retain |pending_task->task| beyond this function call.
bool PostPendingTask(PendingTask* pending_task);
+ // Wakes up the message loop and schedules work.
+ void ScheduleWork();
+
// Number of tasks that require high resolution timing. This value is kept
// so that ReloadWorkQueue() completes in constant time.
int high_res_task_count_;
@@ -92,6 +99,9 @@ class BASE_EXPORT IncomingTaskQueue
// if the incoming queue was not empty.
const bool always_schedule_work_;
+ // False until StartScheduling() is called.
+ bool is_ready_for_scheduling_;
+
DISALLOW_COPY_AND_ASSIGN(IncomingTaskQueue);
};