diff options
-rw-r--r-- | base/threading/sequenced_worker_pool.cc | 62 | ||||
-rw-r--r-- | base/threading/sequenced_worker_pool.h | 6 | ||||
-rw-r--r-- | chrome/browser/crash_upload_list.cc | 4 | ||||
-rw-r--r-- | chrome/browser/visitedlink/visitedlink_master.cc | 22 | ||||
-rw-r--r-- | chrome/browser/visitedlink/visitedlink_master.h | 8 | ||||
-rw-r--r-- | content/browser/browser_main_loop.cc | 8 | ||||
-rw-r--r-- | content/browser/browser_thread_impl.cc | 146 | ||||
-rw-r--r-- | content/browser/browser_thread_impl.h | 2 | ||||
-rw-r--r-- | content/public/browser/browser_thread.h | 29 |
9 files changed, 76 insertions, 211 deletions
diff --git a/base/threading/sequenced_worker_pool.cc b/base/threading/sequenced_worker_pool.cc index 0a3697b..05ccff1 100644 --- a/base/threading/sequenced_worker_pool.cc +++ b/base/threading/sequenced_worker_pool.cc @@ -57,31 +57,20 @@ class SequencedWorkerPool::Inner Inner(size_t max_threads, const std::string& thread_name_prefix); virtual ~Inner(); + // Backends for SequenceWorkerPool. SequenceToken GetSequenceToken(); - SequenceToken GetNamedSequenceToken(const std::string& name); - - // This function accepts a name and an ID. If the name is null, the - // token ID is used. This allows us to implement the optional name lookup - // from a single function without having to enter the lock a separate time. - bool PostTask(const std::string* optional_token_name, - int sequence_token_id, + bool PostTask(int sequence_token_id, SequencedWorkerPool::WorkerShutdown shutdown_behavior, const tracked_objects::Location& from_here, const base::Closure& task); - void Shutdown(); - void SetTestingObserver(SequencedWorkerPool::TestingObserver* observer); // Runs the worker loop on the background thread. void ThreadLoop(Worker* this_worker); private: - // Called from within the lock, this converts the given token name into a - // token ID, creating a new one if necessary. - int LockedGetNamedTokenID(const std::string& name); - // The calling code should clear the given delete_these_oustide_lock // vector the next time the lock is released. See the implementation for // a more detailed description. @@ -246,11 +235,18 @@ SequencedWorkerPool::SequenceToken SequencedWorkerPool::Inner::GetNamedSequenceToken( const std::string& name) { base::AutoLock lock(lock_); - return SequenceToken(LockedGetNamedTokenID(name)); + std::map<std::string, int>::const_iterator found = + named_sequence_tokens_.find(name); + if (found != named_sequence_tokens_.end()) + return SequenceToken(found->second); // Got an existing one. + + // Create a new one for this name. + SequenceToken result = GetSequenceToken(); + named_sequence_tokens_.insert(std::make_pair(name, result.id_)); + return result; } bool SequencedWorkerPool::Inner::PostTask( - const std::string* optional_token_name, int sequence_token_id, SequencedWorkerPool::WorkerShutdown shutdown_behavior, const tracked_objects::Location& from_here, @@ -267,10 +263,6 @@ bool SequencedWorkerPool::Inner::PostTask( if (terminating_) return false; - // Now that we have the lock, apply the named token rules. - if (optional_token_name) - sequenced.sequence_token_id = LockedGetNamedTokenID(*optional_token_name); - pending_tasks_.push_back(sequenced); pending_task_count_++; if (shutdown_behavior == BLOCK_SHUTDOWN) @@ -385,22 +377,6 @@ void SequencedWorkerPool::Inner::ThreadLoop(Worker* this_worker) { cond_var_.Signal(); } -int SequencedWorkerPool::Inner::LockedGetNamedTokenID( - const std::string& name) { - lock_.AssertAcquired(); - DCHECK(!name.empty()); - - std::map<std::string, int>::const_iterator found = - named_sequence_tokens_.find(name); - if (found != named_sequence_tokens_.end()) - return found->second; // Got an existing one. - - // Create a new one for this name. - SequenceToken result = GetSequenceToken(); - named_sequence_tokens_.insert(std::make_pair(name, result.id_)); - return result.id_; -} - bool SequencedWorkerPool::Inner::GetWork( SequencedTask* task, std::vector<base::Closure>* delete_these_outside_lock) { @@ -617,38 +593,30 @@ SequencedWorkerPool::SequenceToken SequencedWorkerPool::GetNamedSequenceToken( bool SequencedWorkerPool::PostWorkerTask( const tracked_objects::Location& from_here, const base::Closure& task) { - return inner_->PostTask(NULL, 0, BLOCK_SHUTDOWN, from_here, task); + return inner_->PostTask(0, BLOCK_SHUTDOWN, from_here, task); } bool SequencedWorkerPool::PostWorkerTaskWithShutdownBehavior( const tracked_objects::Location& from_here, const base::Closure& task, WorkerShutdown shutdown_behavior) { - return inner_->PostTask(NULL, 0, shutdown_behavior, from_here, task); + return inner_->PostTask(0, shutdown_behavior, from_here, task); } bool SequencedWorkerPool::PostSequencedWorkerTask( SequenceToken sequence_token, const tracked_objects::Location& from_here, const base::Closure& task) { - return inner_->PostTask(NULL, sequence_token.id_, BLOCK_SHUTDOWN, + return inner_->PostTask(sequence_token.id_, BLOCK_SHUTDOWN, from_here, task); } -bool SequencedWorkerPool::PostNamedSequencedWorkerTask( - const std::string& token_name, - const tracked_objects::Location& from_here, - const base::Closure& task) { - DCHECK(!token_name.empty()); - return inner_->PostTask(&token_name, 0, BLOCK_SHUTDOWN, from_here, task); -} - bool SequencedWorkerPool::PostSequencedWorkerTaskWithShutdownBehavior( SequenceToken sequence_token, const tracked_objects::Location& from_here, const base::Closure& task, WorkerShutdown shutdown_behavior) { - return inner_->PostTask(NULL, sequence_token.id_, shutdown_behavior, + return inner_->PostTask(sequence_token.id_, shutdown_behavior, from_here, task); } diff --git a/base/threading/sequenced_worker_pool.h b/base/threading/sequenced_worker_pool.h index 71e431c..c6e0560 100644 --- a/base/threading/sequenced_worker_pool.h +++ b/base/threading/sequenced_worker_pool.h @@ -172,12 +172,6 @@ class BASE_EXPORT SequencedWorkerPool { const tracked_objects::Location& from_here, const base::Closure& task); - // Like PostSequencedWorkerTask above, but allows you to specify a named - // token, which saves an extra call to GetNamedSequenceToken. - bool PostNamedSequencedWorkerTask(const std::string& token_name, - const tracked_objects::Location& from_here, - const base::Closure& task); - // Same as PostSequencedWorkerTask but allows specification of the shutdown // behavior. bool PostSequencedWorkerTaskWithShutdownBehavior( diff --git a/chrome/browser/crash_upload_list.cc b/chrome/browser/crash_upload_list.cc index 30c04f8..bc74d8e 100644 --- a/chrome/browser/crash_upload_list.cc +++ b/chrome/browser/crash_upload_list.cc @@ -39,7 +39,8 @@ CrashUploadList::CrashUploadList(Delegate* delegate) : delegate_(delegate) {} CrashUploadList::~CrashUploadList() {} void CrashUploadList::LoadCrashListAsynchronously() { - BrowserThread::PostBlockingPoolTask( + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, base::Bind(&CrashUploadList::LoadCrashListAndInformDelegateOfCompletion, this)); @@ -59,6 +60,7 @@ void CrashUploadList::LoadCrashListAndInformDelegateOfCompletion() { } void CrashUploadList::LoadCrashList() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); FilePath crash_dir_path; PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dir_path); FilePath upload_log_path = crash_dir_path.AppendASCII("uploads.log"); diff --git a/chrome/browser/visitedlink/visitedlink_master.cc b/chrome/browser/visitedlink/visitedlink_master.cc index 38c87ca..f3fbc85 100644 --- a/chrome/browser/visitedlink/visitedlink_master.cc +++ b/chrome/browser/visitedlink/visitedlink_master.cc @@ -191,7 +191,6 @@ void VisitedLinkMaster::InitMembers(Listener* listener, Profile* profile) { history_service_override_ = NULL; suppress_rebuild_ = false; profile_ = profile; - sequence_token_ = BrowserThread::GetBlockingPool()->GetSequenceToken(); #ifndef NDEBUG posted_asynchronous_operation_ = false; @@ -243,12 +242,6 @@ VisitedLinkMaster::Hash VisitedLinkMaster::TryToAddURL(const GURL& url) { return AddFingerprint(fingerprint, true); } -void VisitedLinkMaster::PostIOTask(const tracked_objects::Location& from_here, - const base::Closure& task) { - BrowserThread::GetBlockingPool()->PostSequencedWorkerTask(sequence_token_, - from_here, task); -} - void VisitedLinkMaster::AddURL(const GURL& url) { Hash index = TryToAddURL(url); if (!table_builder_ && index != null_hash_) { @@ -487,7 +480,10 @@ bool VisitedLinkMaster::WriteFullTable() { hash_table_, table_length_ * sizeof(Fingerprint)); // The hash table may have shrunk, so make sure this is the end. - PostIOTask(FROM_HERE, base::Bind(base::IgnoreResult(&TruncateFile), file_)); + BrowserThread::PostTask( + BrowserThread::FILE, + FROM_HERE, + base::Bind(base::IgnoreResult(&TruncateFile), file_)); return true; } @@ -677,7 +673,11 @@ void VisitedLinkMaster::FreeURLTable() { } if (!file_) return; - PostIOTask(FROM_HERE, base::Bind(base::IgnoreResult(&fclose), file_)); + + BrowserThread::PostTask( + BrowserThread::FILE, + FROM_HERE, + base::Bind(base::IgnoreResult(&fclose), file_)); } bool VisitedLinkMaster::ResizeTableIfNecessary() { @@ -860,7 +860,9 @@ void VisitedLinkMaster::WriteToFile(FILE* file, #ifndef NDEBUG posted_asynchronous_operation_ = true; #endif - PostIOTask(FROM_HERE, + + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, base::Bind(&AsyncWrite, file, offset, std::string(static_cast<const char*>(data), data_size))); } diff --git a/chrome/browser/visitedlink/visitedlink_master.h b/chrome/browser/visitedlink/visitedlink_master.h index 1771afe..c84e809 100644 --- a/chrome/browser/visitedlink/visitedlink_master.h +++ b/chrome/browser/visitedlink/visitedlink_master.h @@ -17,7 +17,6 @@ #include "base/gtest_prod_util.h" #include "base/memory/ref_counted.h" #include "base/shared_memory.h" -#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/history/history.h" #include "chrome/common/visitedlink_common.h" @@ -164,10 +163,6 @@ class VisitedLinkMaster : public VisitedLinkCommon { // File I/O functions // ------------------ - // Posts the given task to the blocking worker pool with our options. - void PostIOTask(const tracked_objects::Location& from_here, - const base::Closure& task); - // Writes the entire table to disk, returning true on success. It will leave // the table file open and the handle to it in file_ bool WriteFullTable(); @@ -317,9 +312,6 @@ class VisitedLinkMaster : public VisitedLinkCommon { // (it knows the path to where the data is stored) Profile* profile_; - // Lazily initialized sequence token for posting file tasks. - base::SequencedWorkerPool::SequenceToken sequence_token_; - // When non-NULL, indicates we are in database rebuild mode and points to // the class collecting fingerprint information from the history system. // The pointer is owned by this class, but it must remain valid while the diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index e22fd15..2a1f681 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc @@ -497,14 +497,6 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() { parts_->PostStopThread(id); } - // Close the blocking I/O pool after the other threads. Other threads such - // as the I/O thread may need to schedule work like closing files or flushing - // data during shutdown, so the blocking pool needs to be available. There - // may also be slow operations pending that will blcok shutdown, so closing - // it here (which will block until required operations are complete) gives - // more head start for those operations to finish. - BrowserThreadImpl::ShutdownThreadPool(); - if (parts_.get()) parts_->PostDestroyThreads(); } diff --git a/content/browser/browser_thread_impl.cc b/content/browser/browser_thread_impl.cc index fd86aa5..a66477a 100644 --- a/content/browser/browser_thread_impl.cc +++ b/content/browser/browser_thread_impl.cc @@ -9,7 +9,6 @@ #include "base/lazy_instance.h" #include "base/message_loop.h" #include "base/message_loop_proxy.h" -#include "base/threading/sequenced_worker_pool.h" #include "base/threading/thread_restrictions.h" namespace content { @@ -31,37 +30,24 @@ static const char* g_browser_thread_names[BrowserThread::ID_COUNT] = { #endif }; -struct BrowserThreadGlobals { - BrowserThreadGlobals() - : blocking_pool(new base::SequencedWorkerPool(3, "BrowserBlocking")) { - memset(threads, 0, - BrowserThread::ID_COUNT * sizeof(BrowserThreadImpl*)); - memset(thread_delegates, 0, - BrowserThread::ID_COUNT * sizeof(BrowserThreadDelegate*)); - } - - // This lock protects |threads|. Do not read or modify that array - // without holding this lock. Do not block while holding this lock. - base::Lock lock; - - // This array is protected by |lock|. The threads are not owned by this - // array. Typically, the threads are owned on the UI thread by - // content::BrowserMainLoop. BrowserThreadImpl objects remove themselves from - // this array upon destruction. - BrowserThreadImpl* threads[BrowserThread::ID_COUNT]; - - // Only atomic operations are used on this array. The delegates are not owned - // by this array, rather by whoever calls BrowserThread::SetDelegate. - BrowserThreadDelegate* thread_delegates[BrowserThread::ID_COUNT]; - - // This pointer is deliberately leaked on shutdown. This allows the pool to - // implement "continue on shutdown" semantics. - base::SequencedWorkerPool* blocking_pool; -}; - -base::LazyInstance<BrowserThreadGlobals, - base::LeakyLazyInstanceTraits<BrowserThreadGlobals> > - g_globals = LAZY_INSTANCE_INITIALIZER; +// This lock protects |g_browser_threads|. Do not read or modify that +// array without holding this lock. Do not block while holding this +// lock. +base::LazyInstance<base::Lock, + base::LeakyLazyInstanceTraits<base::Lock> > + g_lock = LAZY_INSTANCE_INITIALIZER; + +// This array is protected by |g_lock|. The threads are not owned by this +// array. Typically, the threads are owned on the UI thread by +// content::BrowserMainLoop. BrowserThreadImpl objects remove +// themselves from this array upon destruction. +static BrowserThreadImpl* g_browser_threads[BrowserThread::ID_COUNT]; + +// Only atomic operations are used on this array. The delegates are +// not owned by this array, rather by whoever calls +// BrowserThread::SetDelegate. +static BrowserThreadDelegate* g_browser_thread_delegates[ + BrowserThread::ID_COUNT]; } // namespace @@ -79,18 +65,10 @@ BrowserThreadImpl::BrowserThreadImpl(ID identifier, Initialize(); } -// static -void BrowserThreadImpl::ShutdownThreadPool() { - BrowserThreadGlobals& globals = g_globals.Get(); - globals.blocking_pool->Shutdown(); -} - void BrowserThreadImpl::Init() { - BrowserThreadGlobals& globals = g_globals.Get(); - using base::subtle::AtomicWord; AtomicWord* storage = - reinterpret_cast<AtomicWord*>(&globals.thread_delegates[identifier_]); + reinterpret_cast<AtomicWord*>(&g_browser_thread_delegates[identifier_]); AtomicWord stored_pointer = base::subtle::NoBarrier_Load(storage); BrowserThreadDelegate* delegate = reinterpret_cast<BrowserThreadDelegate*>(stored_pointer); @@ -99,11 +77,9 @@ void BrowserThreadImpl::Init() { } void BrowserThreadImpl::CleanUp() { - BrowserThreadGlobals& globals = g_globals.Get(); - using base::subtle::AtomicWord; AtomicWord* storage = - reinterpret_cast<AtomicWord*>(&globals.thread_delegates[identifier_]); + reinterpret_cast<AtomicWord*>(&g_browser_thread_delegates[identifier_]); AtomicWord stored_pointer = base::subtle::NoBarrier_Load(storage); BrowserThreadDelegate* delegate = reinterpret_cast<BrowserThreadDelegate*>(stored_pointer); @@ -113,12 +89,10 @@ void BrowserThreadImpl::CleanUp() { } void BrowserThreadImpl::Initialize() { - BrowserThreadGlobals& globals = g_globals.Get(); - - base::AutoLock lock(globals.lock); + base::AutoLock lock(g_lock.Get()); DCHECK(identifier_ >= 0 && identifier_ < ID_COUNT); - DCHECK(globals.threads[identifier_] == NULL); - globals.threads[identifier_] = this; + DCHECK(g_browser_threads[identifier_] == NULL); + g_browser_threads[identifier_] = this; } BrowserThreadImpl::~BrowserThreadImpl() { @@ -127,13 +101,12 @@ BrowserThreadImpl::~BrowserThreadImpl() { // the right BrowserThread. Stop(); - BrowserThreadGlobals& globals = g_globals.Get(); - base::AutoLock lock(globals.lock); - globals.threads[identifier_] = NULL; + base::AutoLock lock(g_lock.Get()); + g_browser_threads[identifier_] = NULL; #ifndef NDEBUG // Double check that the threads are ordered correctly in the enumeration. for (int i = identifier_ + 1; i < ID_COUNT; ++i) { - DCHECK(!globals.threads[i]) << + DCHECK(!g_browser_threads[i]) << "Threads must be listed in the reverse order that they die"; } #endif @@ -158,12 +131,11 @@ bool BrowserThreadImpl::PostTaskHelper( GetCurrentThreadIdentifier(¤t_thread) && current_thread <= identifier; - BrowserThreadGlobals& globals = g_globals.Get(); if (!guaranteed_to_outlive_target_thread) - globals.lock.Acquire(); + g_lock.Get().Acquire(); - MessageLoop* message_loop = globals.threads[identifier] ? - globals.threads[identifier]->message_loop() : NULL; + MessageLoop* message_loop = g_browser_threads[identifier] ? + g_browser_threads[identifier]->message_loop() : NULL; if (message_loop) { if (nestable) { message_loop->PostDelayedTask(from_here, task, delay_ms); @@ -173,7 +145,7 @@ bool BrowserThreadImpl::PostTaskHelper( } if (!guaranteed_to_outlive_target_thread) - globals.lock.Release(); + g_lock.Get().Release(); return !!message_loop; } @@ -220,32 +192,10 @@ class BrowserThreadMessageLoopProxy : public base::MessageLoopProxy { }; // static -bool BrowserThread::PostBlockingPoolTask( - const tracked_objects::Location& from_here, - const base::Closure& task) { - return g_globals.Get().blocking_pool->PostWorkerTask(from_here, task); -} - -// static -bool BrowserThread::PostBlockingPoolSequencedTask( - const std::string& sequence_token_name, - const tracked_objects::Location& from_here, - const base::Closure& task) { - return g_globals.Get().blocking_pool->PostNamedSequencedWorkerTask( - sequence_token_name, from_here, task); -} - -// static -base::SequencedWorkerPool* BrowserThread::GetBlockingPool() { - return g_globals.Get().blocking_pool; -} - -// static bool BrowserThread::IsWellKnownThread(ID identifier) { - BrowserThreadGlobals& globals = g_globals.Get(); - base::AutoLock lock(globals.lock); + base::AutoLock lock(g_lock.Get()); return (identifier >= 0 && identifier < ID_COUNT && - globals.threads[identifier]); + g_browser_threads[identifier]); } // static @@ -255,21 +205,19 @@ bool BrowserThread::CurrentlyOn(ID identifier) { // function. // http://crbug.com/63678 base::ThreadRestrictions::ScopedAllowSingleton allow_singleton; - BrowserThreadGlobals& globals = g_globals.Get(); - base::AutoLock lock(globals.lock); + base::AutoLock lock(g_lock.Get()); DCHECK(identifier >= 0 && identifier < ID_COUNT); - return globals.threads[identifier] && - globals.threads[identifier]->message_loop() == + return g_browser_threads[identifier] && + g_browser_threads[identifier]->message_loop() == MessageLoop::current(); } // static bool BrowserThread::IsMessageLoopValid(ID identifier) { - BrowserThreadGlobals& globals = g_globals.Get(); - base::AutoLock lock(globals.lock); + base::AutoLock lock(g_lock.Get()); DCHECK(identifier >= 0 && identifier < ID_COUNT); - return globals.threads[identifier] && - globals.threads[identifier]->message_loop(); + return g_browser_threads[identifier] && + g_browser_threads[identifier]->message_loop(); } // static @@ -327,11 +275,10 @@ bool BrowserThread::GetCurrentThreadIdentifier(ID* identifier) { // http://crbug.com/63678 base::ThreadRestrictions::ScopedAllowSingleton allow_singleton; MessageLoop* cur_message_loop = MessageLoop::current(); - BrowserThreadGlobals& globals = g_globals.Get(); for (int i = 0; i < ID_COUNT; ++i) { - if (globals.threads[i] && - globals.threads[i]->message_loop() == cur_message_loop) { - *identifier = globals.threads[i]->identifier_; + if (g_browser_threads[i] && + g_browser_threads[i]->message_loop() == cur_message_loop) { + *identifier = g_browser_threads[i]->identifier_; return true; } } @@ -341,7 +288,8 @@ bool BrowserThread::GetCurrentThreadIdentifier(ID* identifier) { // static scoped_refptr<base::MessageLoopProxy> -BrowserThread::GetMessageLoopProxyForThread(ID identifier) { +BrowserThread::GetMessageLoopProxyForThread( + ID identifier) { scoped_refptr<base::MessageLoopProxy> proxy( new BrowserThreadMessageLoopProxy(identifier)); return proxy; @@ -349,9 +297,8 @@ BrowserThread::GetMessageLoopProxyForThread(ID identifier) { // static MessageLoop* BrowserThread::UnsafeGetMessageLoopForThread(ID identifier) { - BrowserThreadGlobals& globals = g_globals.Get(); - base::AutoLock lock(globals.lock); - base::Thread* thread = globals.threads[identifier]; + base::AutoLock lock(g_lock.Get()); + base::Thread* thread = g_browser_threads[identifier]; DCHECK(thread); MessageLoop* loop = thread->message_loop(); return loop; @@ -361,9 +308,8 @@ MessageLoop* BrowserThread::UnsafeGetMessageLoopForThread(ID identifier) { void BrowserThread::SetDelegate(ID identifier, BrowserThreadDelegate* delegate) { using base::subtle::AtomicWord; - BrowserThreadGlobals& globals = g_globals.Get(); AtomicWord* storage = reinterpret_cast<AtomicWord*>( - &globals.thread_delegates[identifier]); + &g_browser_thread_delegates[identifier]); AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( storage, reinterpret_cast<AtomicWord>(delegate)); diff --git a/content/browser/browser_thread_impl.h b/content/browser/browser_thread_impl.h index 4488f85..feea986 100644 --- a/content/browser/browser_thread_impl.h +++ b/content/browser/browser_thread_impl.h @@ -25,8 +25,6 @@ class CONTENT_EXPORT BrowserThreadImpl BrowserThreadImpl(BrowserThread::ID identifier, MessageLoop* message_loop); virtual ~BrowserThreadImpl(); - static void ShutdownThreadPool(); - protected: virtual void Init() OVERRIDE; virtual void CleanUp() OVERRIDE; diff --git a/content/public/browser/browser_thread.h b/content/public/browser/browser_thread.h index 02671c9..53345fa 100644 --- a/content/public/browser/browser_thread.h +++ b/content/public/browser/browser_thread.h @@ -20,7 +20,6 @@ class MessageLoop; namespace base { -class SequencedWorkerPool; class Thread; } @@ -140,34 +139,6 @@ class CONTENT_EXPORT BrowserThread { from_here, object); } - // Simplified wrappers for posting to the blocking thread pool. Use this - // for doing things like blocking I/O. - // - // The first variant will run the task in the pool with no sequencing - // semantics, so may get run in parallel with other posted tasks. The - // second variant provides sequencing between tasks with the same - // sequence token name. - // - // These tasks are guaranteed to run before shutdown. - // - // If you need to provide different shutdown semantics (like you have - // something slow and noncritical that doesn't need to block shutdown), - // or you want to manually provide a sequence token (which saves a map - // lookup and is guaranteed unique without you having to come up with a - // unique string), you can access the sequenced worker pool directly via - // GetBlockingPool(). - static bool PostBlockingPoolTask(const tracked_objects::Location& from_here, - const base::Closure& task); - static bool PostBlockingPoolSequencedTask( - const std::string& sequence_token_name, - const tracked_objects::Location& from_here, - const base::Closure& task); - - // Returns the thread pool used for blocking file I/O. Use this object to - // perform random blocking operations such as file writes or querying the - // Windows registry. - static base::SequencedWorkerPool* GetBlockingPool(); - // Callable on any thread. Returns whether the given ID corresponds to a well // known thread. static bool IsWellKnownThread(ID identifier); |