15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CONTENT_PUBLIC_BROWSER_BROWSER_THREAD_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CONTENT_PUBLIC_BROWSER_BROWSER_THREAD_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/logging.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/task_runner_util.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/content_export.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MessageLoop; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SequencedWorkerPool; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Thread; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BrowserThreadDelegate; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BrowserThreadImpl; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use DCHECK_CURRENTLY_ON(BrowserThread::ID) to assert that a function can only 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// be called on the named BrowserThread. 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define DCHECK_CURRENTLY_ON(thread_identifier) \ 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) (DCHECK(::content::BrowserThread::CurrentlyOn(thread_identifier)) \ 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << ::content::BrowserThread::GetDCheckCurrentlyOnErrorMessage( \ 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) thread_identifier)) 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BrowserThread 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Utility functions for threads that are known by a browser-wide 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// name. For example, there is one IO thread for the entire browser 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// process, and various pieces of code find it useful to retrieve a 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pointer to the IO thread's message loop. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Invoke a task by thread ID: 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, task); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The return value is false if the task couldn't be posted because the target 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thread doesn't exist. If this could lead to data loss, you need to check the 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// result and restructure the code to ensure it doesn't occur. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class automatically handles the lifetime of different threads. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It's always safe to call PostTask on any thread. If it's not yet created, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the task is deleted. There are no race conditions. If the thread that the 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// task is posted to is guaranteed to outlive the current thread, then no locks 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are used. You should never need to cache pointers to MessageLoops, since 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// they're not thread safe. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CONTENT_EXPORT BrowserThread { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An enumeration of the well-known threads. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: threads must be listed in the order of their life-time, with each 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread outliving every other thread below it. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum ID { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The main thread in the browser. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UI, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the thread that interacts with the database. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DB, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the thread that interacts with the file system. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used for file system operations that block user interactions. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Responsiveness of this thread affect users. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE_USER_BLOCKING, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used to launch and terminate Chrome processes. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PROCESS_LAUNCHER, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the thread to handle slow HTTP cache operations. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CACHE, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the thread that processes IPC and network messages. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IO, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: do not add new threads here that are only used by a small number of 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // files. Instead you should just use a Thread class and pass its 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MessageLoopProxy around. Named threads there are only for threads that 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are used in many places. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This identifier does not represent a thread. Instead it counts the 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // number of well-known threads. Insert new well-known threads before this 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // identifier. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ID_COUNT 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These are the same methods in message_loop.h, but are guaranteed to either 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // get posted to the MessageLoop if it's still alive, or be deleted otherwise. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // They return true iff the thread existed and the task was posted. Note that 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // even if the task is posted, there's no guarantee that it will run, since 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the target thread may already have a Quit message in its queue. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool PostTask(ID identifier, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool PostDelayedTask(ID identifier, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta delay); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool PostNonNestableTask(ID identifier, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool PostNonNestableDelayedTask( 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ID identifier, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta delay); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool PostTaskAndReply( 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ID identifier, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& reply); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename ReturnType, typename ReplyArgType> 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool PostTaskAndReplyWithResult( 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ID identifier, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<ReturnType(void)>& task, 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Callback<void(ReplyArgType)>& reply) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> message_loop_proxy = 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetMessageLoopProxyForThread(identifier); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::PostTaskAndReplyWithResult( 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_proxy.get(), from_here, task, reply); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <class T> 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool DeleteSoon(ID identifier, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const T* object) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetMessageLoopProxyForThread(identifier)->DeleteSoon( 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) from_here, object); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <class T> 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool ReleaseSoon(ID identifier, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const T* object) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetMessageLoopProxyForThread(identifier)->ReleaseSoon( 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) from_here, object); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Simplified wrappers for posting to the blocking thread pool. Use this 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for doing things like blocking I/O. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first variant will run the task in the pool with no sequencing 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // semantics, so may get run in parallel with other posted tasks. The second 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // variant will all post a task with no sequencing semantics, and will post a 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reply task to the origin TaskRunner upon completion. The third variant 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // provides sequencing between tasks with the same sequence token name. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These tasks are guaranteed to run before shutdown. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If you need to provide different shutdown semantics (like you have 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // something slow and noncritical that doesn't need to block shutdown), 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or you want to manually provide a sequence token (which saves a map 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // lookup and is guaranteed unique without you having to come up with a 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unique string), you can access the sequenced worker pool directly via 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetBlockingPool(). 170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If you need to PostTaskAndReplyWithResult, use 172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // base::PostTaskAndReplyWithResult() with GetBlockingPool() as the task 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // runner. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool PostBlockingPoolTask(const tracked_objects::Location& from_here, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool PostBlockingPoolTaskAndReply( 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& reply); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool PostBlockingPoolSequencedTask( 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& sequence_token_name, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the thread pool used for blocking file I/O. Use this object to 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // perform random blocking operations such as file writes or querying the 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Windows registry. 1885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static base::SequencedWorkerPool* GetBlockingPool() WARN_UNUSED_RESULT; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 190ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Callable on any thread. Returns whether the given well-known thread is 191ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // initialized. 1925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static bool IsThreadInitialized(ID identifier) WARN_UNUSED_RESULT; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Callable on any thread. Returns whether you're currently on a particular 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // thread. To DCHECK this, use the DCHECK_CURRENTLY_ON() macro above. 1965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static bool CurrentlyOn(ID identifier) WARN_UNUSED_RESULT; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Callable on any thread. Returns whether the threads message loop is valid. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this returns false it means the thread is in the process of shutting 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // down. 2015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static bool IsMessageLoopValid(ID identifier) WARN_UNUSED_RESULT; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the current message loop is one of the known threads, returns true and 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sets identifier to its ID. Otherwise returns false. 2055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static bool GetCurrentThreadIdentifier(ID* identifier) WARN_UNUSED_RESULT; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Callers can hold on to a refcounted MessageLoopProxy beyond the lifetime 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the thread. 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static scoped_refptr<base::MessageLoopProxy> GetMessageLoopProxyForThread( 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ID identifier); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns a pointer to the thread's message loop, which will become 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // invalid during shutdown, so you probably shouldn't hold onto it. 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This must not be called before the thread is started, or after 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the thread is stopped, or it will DCHECK. 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ownership remains with the BrowserThread implementation, so you 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // must not delete the pointer. 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static base::MessageLoop* UnsafeGetMessageLoopForThread(ID identifier); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sets the delegate for the specified BrowserThread. 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only one delegate may be registered at a time. Delegates may be 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unregistered by providing a NULL pointer. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the caller unregisters a delegate before CleanUp has been 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // called, it must perform its own locking to ensure the delegate is 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not deleted while unregistering. 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void SetDelegate(ID identifier, BrowserThreadDelegate* delegate); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use these templates in conjuction with RefCountedThreadSafe when you want 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to ensure that an object is deleted on a specific thread. This is needed 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when an object can hop between threads (i.e. IO -> FILE -> IO), and thread 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // switching delays can mean that the final IO tasks executes before the FILE 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // task's stack unwinds. This would lead to the object destructing on the 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FILE thread, which often is not what you want (i.e. to unregister from 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NotificationService, to notify other objects on the creating thread etc). 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template<ID thread> 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct DeleteOnThread { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template<typename T> 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void Destruct(const T* x) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CurrentlyOn(thread)) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete x; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!DeleteSoon(thread, FROM_HERE, x)) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(UNIT_TEST) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only logged under unit testing because leaks at shutdown 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are acceptable under normal circumstances. 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "DeleteSoon failed on thread " << thread; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // UNIT_TEST 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sample usage: 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // class Foo 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // : public base::RefCountedThreadSafe< 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Foo, BrowserThread::DeleteOnIOThread> { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ... 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // private: 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // friend class base::DeleteHelper<Foo>; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ~Foo(); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct DeleteOnUIThread : public DeleteOnThread<UI> { }; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct DeleteOnIOThread : public DeleteOnThread<IO> { }; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct DeleteOnFileThread : public DeleteOnThread<FILE> { }; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct DeleteOnDBThread : public DeleteOnThread<DB> { }; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Returns an appropriate error message for when DCHECK_CURRENTLY_ON() fails. 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static std::string GetDCheckCurrentlyOnErrorMessage(ID expected); 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class BrowserThreadImpl; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread() {} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BrowserThread); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CONTENT_PUBLIC_BROWSER_BROWSER_THREAD_H_ 286