Chromium Code Reviews| Index: components/history/core/browser/history_service.cc |
| diff --git a/components/history/core/browser/history_service.cc b/components/history/core/browser/history_service.cc |
| index a97677666b691d765a49bbc921453c2bdda7d277..17459db5e070f6a0733e8d27fe769a3178b91c41 100644 |
| --- a/components/history/core/browser/history_service.cc |
| +++ b/components/history/core/browser/history_service.cc |
| @@ -28,6 +28,7 @@ |
| #include "base/memory/ref_counted.h" |
| #include "base/metrics/histogram_macros.h" |
| #include "base/single_thread_task_runner.h" |
| +#include "base/task_scheduler/post_task.h" |
| #include "base/threading/thread.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| #include "base/time/time.h" |
| @@ -62,6 +63,17 @@ namespace { |
| static const char* kHistoryThreadName = "Chrome_HistoryThread"; |
| +// Whether HistoryBackend tasks should run on a TaskScheduler sequence rather |
| +// than on a dedicated thread. |
| +// TODO(fdoray): Remove once the HistoryService redirection experiment |
| +// concludes. https://crbug.com/661143 |
| +bool g_redirected_to_task_scheduler = false; |
| + |
| +// Whether an HistoryService has been instantiated in the current process. |
| +// TODO(fdoray): Remove once the HistoryService redirection experiment |
| +// concludes. https://crbug.com/661143 |
| +bool g_instantiated_history_service = false; |
| + |
| void RunWithFaviconResults( |
| const favicon_base::FaviconResultsCallback& callback, |
| std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { |
| @@ -182,23 +194,19 @@ class HistoryService::BackendDelegate : public HistoryBackend::Delegate { |
| const scoped_refptr<base::SequencedTaskRunner> service_task_runner_; |
| }; |
| -// The history thread is intentionally not a BrowserThread because the |
| -// sync integration unit tests depend on being able to create more than one |
| -// history thread. |
| -HistoryService::HistoryService() |
| - : thread_(new base::Thread(kHistoryThreadName)), |
| - history_client_(nullptr), |
| - backend_loaded_(false), |
| - weak_ptr_factory_(this) { |
| -} |
| +HistoryService::HistoryService() : HistoryService(nullptr, nullptr) {} |
| HistoryService::HistoryService(std::unique_ptr<HistoryClient> history_client, |
| std::unique_ptr<VisitDelegate> visit_delegate) |
| - : thread_(new base::Thread(kHistoryThreadName)), |
| + : thread_(g_redirected_to_task_scheduler |
| + ? nullptr |
| + : new base::Thread(kHistoryThreadName)), |
| history_client_(std::move(history_client)), |
| visit_delegate_(std::move(visit_delegate)), |
| backend_loaded_(false), |
| - weak_ptr_factory_(this) {} |
| + weak_ptr_factory_(this) { |
| + g_instantiated_history_service = true; |
| +} |
| HistoryService::~HistoryService() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| @@ -206,6 +214,12 @@ HistoryService::~HistoryService() { |
| Cleanup(); |
| } |
| +void HistoryService::RedirectToTaskSchedulerForProcess() { |
| + DCHECK(!g_instantiated_history_service); |
| + DCHECK(!g_redirected_to_task_scheduler); |
| + g_redirected_to_task_scheduler = true; |
| +} |
| + |
| bool HistoryService::BackendLoaded() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| return backend_loaded_; |
| @@ -213,7 +227,7 @@ bool HistoryService::BackendLoaded() { |
| #if defined(OS_IOS) |
| void HistoryService::HandleBackgrounding() { |
| - if (!thread_ || !history_backend_.get()) |
| + if (!backend_task_runner_ || !history_backend_.get()) |
| return; |
| ScheduleTask(PRIORITY_NORMAL, |
| @@ -223,7 +237,7 @@ void HistoryService::HandleBackgrounding() { |
| #endif |
| void HistoryService::ClearCachedDataForContextID(ContextID context_id) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| ScheduleTask(PRIORITY_NORMAL, |
| base::Bind(&HistoryBackend::ClearCachedDataForContextID, |
| @@ -247,7 +261,7 @@ void HistoryService::Shutdown() { |
| void HistoryService::SetKeywordSearchTermsForURL(const GURL& url, |
| KeywordID keyword_id, |
| const base::string16& term) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| ScheduleTask(PRIORITY_UI, |
| base::Bind(&HistoryBackend::SetKeywordSearchTermsForURL, |
| @@ -255,7 +269,7 @@ void HistoryService::SetKeywordSearchTermsForURL(const GURL& url, |
| } |
| void HistoryService::DeleteAllSearchTermsForKeyword(KeywordID keyword_id) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| if (in_memory_backend_) |
| @@ -267,7 +281,7 @@ void HistoryService::DeleteAllSearchTermsForKeyword(KeywordID keyword_id) { |
| } |
| void HistoryService::DeleteKeywordSearchTermForURL(const GURL& url) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| ScheduleTask(PRIORITY_UI, |
| base::Bind(&HistoryBackend::DeleteKeywordSearchTermForURL, |
| @@ -276,7 +290,7 @@ void HistoryService::DeleteKeywordSearchTermForURL(const GURL& url) { |
| void HistoryService::DeleteMatchingURLsForKeyword(KeywordID keyword_id, |
| const base::string16& term) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| ScheduleTask(PRIORITY_UI, |
| base::Bind(&HistoryBackend::DeleteMatchingURLsForKeyword, |
| @@ -284,7 +298,7 @@ void HistoryService::DeleteMatchingURLsForKeyword(KeywordID keyword_id, |
| } |
| void HistoryService::URLsNoLongerBookmarked(const std::set<GURL>& urls) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| ScheduleTask(PRIORITY_NORMAL, |
| base::Bind(&HistoryBackend::URLsNoLongerBookmarked, |
| @@ -304,7 +318,7 @@ void HistoryService::RemoveObserver(HistoryServiceObserver* observer) { |
| base::CancelableTaskTracker::TaskId HistoryService::ScheduleDBTask( |
| std::unique_ptr<HistoryDBTask> task, |
| base::CancelableTaskTracker* tracker) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| base::CancelableTaskTracker::IsCanceledCallback is_canceled; |
| base::CancelableTaskTracker::TaskId task_id = |
| @@ -312,20 +326,20 @@ base::CancelableTaskTracker::TaskId HistoryService::ScheduleDBTask( |
| // Use base::ThreadTaskRunnerHandler::Get() to get a task runner for |
| // the current message loop so that we can forward the call to the method |
| // HistoryDBTask::DoneRunOnMainThread() in the correct thread. |
| - thread_->task_runner()->PostTask( |
| - FROM_HERE, base::Bind(&HistoryBackend::ProcessDBTask, |
| - history_backend_, base::Passed(&task), |
| + backend_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&HistoryBackend::ProcessDBTask, history_backend_, |
| + base::Passed(&task), |
| base::ThreadTaskRunnerHandle::Get(), is_canceled)); |
| return task_id; |
| } |
| void HistoryService::FlushForTest(const base::Closure& flushed) { |
| - thread_->task_runner()->PostTaskAndReply( |
| - FROM_HERE, base::Bind(&base::DoNothing), flushed); |
| + backend_task_runner_->PostTaskAndReply(FROM_HERE, |
| + base::Bind(&base::DoNothing), flushed); |
| } |
| void HistoryService::SetOnBackendDestroyTask(const base::Closure& task) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| ScheduleTask( |
| PRIORITY_NORMAL, |
| @@ -335,10 +349,10 @@ void HistoryService::SetOnBackendDestroyTask(const base::Closure& task) { |
| void HistoryService::TopHosts(size_t num_hosts, |
| const TopHostsCallback& callback) const { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| PostTaskAndReplyWithResult( |
| - thread_->task_runner().get(), FROM_HERE, |
| + backend_task_runner_.get(), FROM_HERE, |
| base::Bind(&HistoryBackend::TopHosts, history_backend_, num_hosts), |
| callback); |
| } |
| @@ -346,10 +360,10 @@ void HistoryService::TopHosts(size_t num_hosts, |
| void HistoryService::GetCountsAndLastVisitForOrigins( |
| const std::set<GURL>& origins, |
| const GetCountsAndLastVisitForOriginsCallback& callback) const { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| PostTaskAndReplyWithResult( |
| - thread_->task_runner().get(), FROM_HERE, |
| + backend_task_runner_.get(), FROM_HERE, |
| base::Bind(&HistoryBackend::GetCountsAndLastVisitForOrigins, |
| history_backend_, origins), |
| callback); |
| @@ -358,12 +372,12 @@ void HistoryService::GetCountsAndLastVisitForOrigins( |
| void HistoryService::HostRankIfAvailable( |
| const GURL& url, |
| const base::Callback<void(int)>& callback) const { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - PostTaskAndReplyWithResult(thread_->task_runner().get(), FROM_HERE, |
| - base::Bind(&HistoryBackend::HostRankIfAvailable, |
| - history_backend_, url), |
| - callback); |
| + PostTaskAndReplyWithResult( |
| + backend_task_runner_.get(), FROM_HERE, |
| + base::Bind(&HistoryBackend::HostRankIfAvailable, history_backend_, url), |
| + callback); |
| } |
| void HistoryService::AddPage(const GURL& url, |
| @@ -391,7 +405,7 @@ void HistoryService::AddPage(const GURL& url, |
| } |
| void HistoryService::AddPage(const HistoryAddPageArgs& add_page_args) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| // Filter out unwanted URLs. We don't add auto-subframe URLs. They are a |
| @@ -422,7 +436,7 @@ void HistoryService::AddPage(const HistoryAddPageArgs& add_page_args) { |
| void HistoryService::AddPageNoVisitForBookmark(const GURL& url, |
| const base::string16& title) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| if (history_client_ && !history_client_->CanAddURL(url)) |
| return; |
| @@ -434,7 +448,7 @@ void HistoryService::AddPageNoVisitForBookmark(const GURL& url, |
| void HistoryService::SetPageTitle(const GURL& url, |
| const base::string16& title) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| ScheduleTask(PRIORITY_NORMAL, base::Bind(&HistoryBackend::SetPageTitle, |
| history_backend_, url, title)); |
| @@ -444,7 +458,7 @@ void HistoryService::UpdateWithPageEndTime(ContextID context_id, |
| int nav_entry_id, |
| const GURL& url, |
| Time end_ts) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| ScheduleTask( |
| PRIORITY_NORMAL, |
| @@ -459,7 +473,7 @@ void HistoryService::AddPageWithDetails(const GURL& url, |
| Time last_visit, |
| bool hidden, |
| VisitSource visit_source) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| // Filter out unwanted URLs. |
| if (history_client_ && !history_client_->CanAddURL(url)) |
| @@ -486,7 +500,7 @@ void HistoryService::AddPageWithDetails(const GURL& url, |
| void HistoryService::AddPagesWithDetails(const URLRows& info, |
| VisitSource visit_source) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| // Inform the VisitDelegate of the URLs |
| @@ -510,14 +524,14 @@ base::CancelableTaskTracker::TaskId HistoryService::GetFavicons( |
| const favicon_base::FaviconResultsCallback& callback, |
| base::CancelableTaskTracker* tracker) { |
| TRACE_EVENT0("browser", "HistoryService::GetFavicons"); |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| std::vector<favicon_base::FaviconRawBitmapResult>* results = |
| new std::vector<favicon_base::FaviconRawBitmapResult>(); |
| return tracker->PostTaskAndReply( |
| - thread_->task_runner().get(), FROM_HERE, |
| - base::Bind(&HistoryBackend::GetFavicons, history_backend_, |
| - icon_urls, icon_types, desired_sizes, results), |
| + backend_task_runner_.get(), FROM_HERE, |
| + base::Bind(&HistoryBackend::GetFavicons, history_backend_, icon_urls, |
| + icon_types, desired_sizes, results), |
| base::Bind(&RunWithFaviconResults, callback, base::Owned(results))); |
| } |
| @@ -528,14 +542,14 @@ base::CancelableTaskTracker::TaskId HistoryService::GetFaviconsForURL( |
| const favicon_base::FaviconResultsCallback& callback, |
| base::CancelableTaskTracker* tracker) { |
| TRACE_EVENT0("browser", "HistoryService::GetFaviconsForURL"); |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| std::vector<favicon_base::FaviconRawBitmapResult>* results = |
| new std::vector<favicon_base::FaviconRawBitmapResult>(); |
| return tracker->PostTaskAndReply( |
| - thread_->task_runner().get(), FROM_HERE, |
| - base::Bind(&HistoryBackend::GetFaviconsForURL, history_backend_, |
| - page_url, icon_types, desired_sizes, results), |
| + backend_task_runner_.get(), FROM_HERE, |
| + base::Bind(&HistoryBackend::GetFaviconsForURL, history_backend_, page_url, |
| + icon_types, desired_sizes, results), |
| base::Bind(&RunWithFaviconResults, callback, base::Owned(results))); |
| } |
| @@ -545,15 +559,14 @@ base::CancelableTaskTracker::TaskId HistoryService::GetLargestFaviconForURL( |
| int minimum_size_in_pixels, |
| const favicon_base::FaviconRawBitmapCallback& callback, |
| base::CancelableTaskTracker* tracker) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| favicon_base::FaviconRawBitmapResult* result = |
| new favicon_base::FaviconRawBitmapResult(); |
| return tracker->PostTaskAndReply( |
| - thread_->task_runner().get(), FROM_HERE, |
| - base::Bind(&HistoryBackend::GetLargestFaviconForURL, |
| - history_backend_, page_url, icon_types, |
| - minimum_size_in_pixels, result), |
| + backend_task_runner_.get(), FROM_HERE, |
| + base::Bind(&HistoryBackend::GetLargestFaviconForURL, history_backend_, |
| + page_url, icon_types, minimum_size_in_pixels, result), |
| base::Bind(&RunWithFaviconResult, callback, base::Owned(result))); |
| } |
| @@ -563,14 +576,14 @@ base::CancelableTaskTracker::TaskId HistoryService::GetFaviconForID( |
| const favicon_base::FaviconResultsCallback& callback, |
| base::CancelableTaskTracker* tracker) { |
| TRACE_EVENT0("browser", "HistoryService::GetFaviconForID"); |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| std::vector<favicon_base::FaviconRawBitmapResult>* results = |
| new std::vector<favicon_base::FaviconRawBitmapResult>(); |
| return tracker->PostTaskAndReply( |
| - thread_->task_runner().get(), FROM_HERE, |
| - base::Bind(&HistoryBackend::GetFaviconForID, history_backend_, |
| - favicon_id, desired_size, results), |
| + backend_task_runner_.get(), FROM_HERE, |
| + base::Bind(&HistoryBackend::GetFaviconForID, history_backend_, favicon_id, |
| + desired_size, results), |
| base::Bind(&RunWithFaviconResults, callback, base::Owned(results))); |
| } |
| @@ -583,12 +596,12 @@ HistoryService::UpdateFaviconMappingsAndFetch( |
| const favicon_base::FaviconResultsCallback& callback, |
| base::CancelableTaskTracker* tracker) { |
| TRACE_EVENT0("browser", "HistoryService::UpdateFaviconMappingsAndFetch"); |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| std::vector<favicon_base::FaviconRawBitmapResult>* results = |
| new std::vector<favicon_base::FaviconRawBitmapResult>(); |
| return tracker->PostTaskAndReply( |
| - thread_->task_runner().get(), FROM_HERE, |
| + backend_task_runner_.get(), FROM_HERE, |
| base::Bind(&HistoryBackend::UpdateFaviconMappingsAndFetch, |
| history_backend_, page_url, icon_urls, icon_types, |
| desired_sizes, results), |
| @@ -602,7 +615,7 @@ void HistoryService::MergeFavicon( |
| scoped_refptr<base::RefCountedMemory> bitmap_data, |
| const gfx::Size& pixel_size) { |
| TRACE_EVENT0("browser", "HistoryService::MergeFavicon"); |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| if (history_client_ && !history_client_->CanAddURL(page_url)) |
| return; |
| @@ -617,7 +630,7 @@ void HistoryService::SetFavicons(const GURL& page_url, |
| favicon_base::IconType icon_type, |
| const GURL& icon_url, |
| const std::vector<SkBitmap>& bitmaps) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| if (history_client_ && !history_client_->CanAddURL(page_url)) |
| return; |
| @@ -628,7 +641,7 @@ void HistoryService::SetFavicons(const GURL& page_url, |
| } |
| void HistoryService::SetFaviconsOutOfDateForPage(const GURL& page_url) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| ScheduleTask(PRIORITY_NORMAL, |
| base::Bind(&HistoryBackend::SetFaviconsOutOfDateForPage, |
| @@ -637,7 +650,7 @@ void HistoryService::SetFaviconsOutOfDateForPage(const GURL& page_url) { |
| void HistoryService::SetImportedFavicons( |
| const favicon_base::FaviconUsageDataList& favicon_usage) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| ScheduleTask(PRIORITY_NORMAL, |
| base::Bind(&HistoryBackend::SetImportedFavicons, |
| @@ -649,13 +662,13 @@ base::CancelableTaskTracker::TaskId HistoryService::QueryURL( |
| bool want_visits, |
| const QueryURLCallback& callback, |
| base::CancelableTaskTracker* tracker) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| QueryURLResult* query_url_result = new QueryURLResult(); |
| return tracker->PostTaskAndReply( |
| - thread_->task_runner().get(), FROM_HERE, |
| - base::Bind(&HistoryBackend::QueryURL, history_backend_, url, |
| - want_visits, base::Unretained(query_url_result)), |
| + backend_task_runner_.get(), FROM_HERE, |
| + base::Bind(&HistoryBackend::QueryURL, history_backend_, url, want_visits, |
| + base::Unretained(query_url_result)), |
| base::Bind(&RunWithQueryURLResult, callback, |
| base::Owned(query_url_result))); |
| } |
| @@ -667,14 +680,12 @@ base::CancelableTaskTracker::TaskId HistoryService::GetHistoryCount( |
| const Time& end_time, |
| const GetHistoryCountCallback& callback, |
| base::CancelableTaskTracker* tracker) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| return tracker->PostTaskAndReplyWithResult( |
| - thread_->task_runner().get(), FROM_HERE, |
| - base::Bind(&HistoryBackend::GetHistoryCount, |
| - history_backend_, |
| - begin_time, |
| + backend_task_runner_.get(), FROM_HERE, |
| + base::Bind(&HistoryBackend::GetHistoryCount, history_backend_, begin_time, |
| end_time), |
| callback); |
| } |
| @@ -686,19 +697,19 @@ base::CancelableTaskTracker::TaskId HistoryService::GetHistoryCount( |
| void HistoryService::CreateDownload( |
| const DownloadRow& create_info, |
| const HistoryService::DownloadCreateCallback& callback) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - PostTaskAndReplyWithResult(thread_->task_runner().get(), FROM_HERE, |
| + PostTaskAndReplyWithResult(backend_task_runner_.get(), FROM_HERE, |
| base::Bind(&HistoryBackend::CreateDownload, |
| history_backend_, create_info), |
| callback); |
| } |
| void HistoryService::GetNextDownloadId(const DownloadIdCallback& callback) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| PostTaskAndReplyWithResult( |
| - thread_->task_runner().get(), FROM_HERE, |
| + backend_task_runner_.get(), FROM_HERE, |
| base::Bind(&HistoryBackend::GetNextDownloadId, history_backend_), |
| callback); |
| } |
| @@ -706,7 +717,7 @@ void HistoryService::GetNextDownloadId(const DownloadIdCallback& callback) { |
| // Handle queries for a list of all downloads in the history database's |
| // 'downloads' table. |
| void HistoryService::QueryDownloads(const DownloadQueryCallback& callback) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| std::vector<DownloadRow>* rows = new std::vector<DownloadRow>(); |
| std::unique_ptr<std::vector<DownloadRow>> scoped_rows(rows); |
| @@ -714,7 +725,7 @@ void HistoryService::QueryDownloads(const DownloadQueryCallback& callback) { |
| // base::Passed(&scoped_rows) nullifies |scoped_rows|, and compilers do not |
| // guarantee that the first Bind's arguments are evaluated before the second |
| // Bind's arguments. |
| - thread_->task_runner()->PostTaskAndReply( |
| + backend_task_runner_->PostTaskAndReply( |
| FROM_HERE, |
| base::Bind(&HistoryBackend::QueryDownloads, history_backend_, rows), |
| base::Bind(callback, base::Passed(&scoped_rows))); |
| @@ -723,14 +734,14 @@ void HistoryService::QueryDownloads(const DownloadQueryCallback& callback) { |
| // Handle updates for a particular download. This is a 'fire and forget' |
| // operation, so we don't need to be called back. |
| void HistoryService::UpdateDownload(const DownloadRow& data) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| ScheduleTask(PRIORITY_NORMAL, base::Bind(&HistoryBackend::UpdateDownload, |
| history_backend_, data)); |
| } |
| void HistoryService::RemoveDownloads(const std::set<uint32_t>& ids) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| ScheduleTask(PRIORITY_NORMAL, base::Bind(&HistoryBackend::RemoveDownloads, |
| history_backend_, ids)); |
| @@ -741,13 +752,13 @@ base::CancelableTaskTracker::TaskId HistoryService::QueryHistory( |
| const QueryOptions& options, |
| const QueryHistoryCallback& callback, |
| base::CancelableTaskTracker* tracker) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| QueryResults* query_results = new QueryResults(); |
| return tracker->PostTaskAndReply( |
| - thread_->task_runner().get(), FROM_HERE, |
| - base::Bind(&HistoryBackend::QueryHistory, history_backend_, |
| - text_query, options, base::Unretained(query_results)), |
| + backend_task_runner_.get(), FROM_HERE, |
| + base::Bind(&HistoryBackend::QueryHistory, history_backend_, text_query, |
| + options, base::Unretained(query_results)), |
| base::Bind(callback, base::Owned(query_results))); |
| } |
| @@ -755,11 +766,11 @@ base::CancelableTaskTracker::TaskId HistoryService::QueryRedirectsFrom( |
| const GURL& from_url, |
| const QueryRedirectsCallback& callback, |
| base::CancelableTaskTracker* tracker) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| RedirectList* result = new RedirectList(); |
| return tracker->PostTaskAndReply( |
| - thread_->task_runner().get(), FROM_HERE, |
| + backend_task_runner_.get(), FROM_HERE, |
| base::Bind(&HistoryBackend::QueryRedirectsFrom, history_backend_, |
| from_url, base::Unretained(result)), |
| base::Bind(callback, base::Owned(result))); |
| @@ -769,13 +780,13 @@ base::CancelableTaskTracker::TaskId HistoryService::QueryRedirectsTo( |
| const GURL& to_url, |
| const QueryRedirectsCallback& callback, |
| base::CancelableTaskTracker* tracker) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| RedirectList* result = new RedirectList(); |
| return tracker->PostTaskAndReply( |
| - thread_->task_runner().get(), FROM_HERE, |
| - base::Bind(&HistoryBackend::QueryRedirectsTo, history_backend_, |
| - to_url, base::Unretained(result)), |
| + backend_task_runner_.get(), FROM_HERE, |
| + base::Bind(&HistoryBackend::QueryRedirectsTo, history_backend_, to_url, |
| + base::Unretained(result)), |
| base::Bind(callback, base::Owned(result))); |
| } |
| @@ -783,13 +794,13 @@ base::CancelableTaskTracker::TaskId HistoryService::GetVisibleVisitCountToHost( |
| const GURL& url, |
| const GetVisibleVisitCountToHostCallback& callback, |
| base::CancelableTaskTracker* tracker) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| VisibleVisitCountToHostResult* result = new VisibleVisitCountToHostResult(); |
| return tracker->PostTaskAndReply( |
| - thread_->task_runner().get(), FROM_HERE, |
| - base::Bind(&HistoryBackend::GetVisibleVisitCountToHost, |
| - history_backend_, url, base::Unretained(result)), |
| + backend_task_runner_.get(), FROM_HERE, |
| + base::Bind(&HistoryBackend::GetVisibleVisitCountToHost, history_backend_, |
| + url, base::Unretained(result)), |
| base::Bind(&RunWithVisibleVisitCountToHostResult, callback, |
| base::Owned(result))); |
| } |
| @@ -799,11 +810,11 @@ base::CancelableTaskTracker::TaskId HistoryService::QueryMostVisitedURLs( |
| int days_back, |
| const QueryMostVisitedURLsCallback& callback, |
| base::CancelableTaskTracker* tracker) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| MostVisitedURLList* result = new MostVisitedURLList(); |
| return tracker->PostTaskAndReply( |
| - thread_->task_runner().get(), FROM_HERE, |
| + backend_task_runner_.get(), FROM_HERE, |
| base::Bind(&HistoryBackend::QueryMostVisitedURLs, history_backend_, |
| result_count, days_back, base::Unretained(result)), |
| base::Bind(callback, base::Owned(result))); |
| @@ -811,7 +822,7 @@ base::CancelableTaskTracker::TaskId HistoryService::QueryMostVisitedURLs( |
| void HistoryService::Cleanup() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - if (!thread_) { |
| + if (!backend_task_runner_) { |
| // We've already cleaned up. |
| return; |
| } |
| @@ -856,15 +867,14 @@ void HistoryService::Cleanup() { |
| closing_task.Reset(); |
| HistoryBackend* raw_ptr = history_backend_.get(); |
| history_backend_ = nullptr; |
| - thread_->task_runner()->ReleaseSoon(FROM_HERE, raw_ptr); |
| + backend_task_runner_->ReleaseSoon(FROM_HERE, raw_ptr); |
| } |
| - // Delete the thread, which joins with the background thread. We defensively |
| - // nullptr the pointer before deleting it in case somebody tries to use it |
| - // during shutdown, but this shouldn't happen. |
| - base::Thread* thread = thread_; |
| - thread_ = nullptr; |
| - delete thread; |
| + // Clear |backend_task_runner_| to make sure it's not used after Cleanup(). |
| + backend_task_runner_ = nullptr; |
|
gab
2016/11/08 19:15:43
To mimic identical shutdown behavior here while in
|
| + |
| + // Join the background thread, if any. |
| + thread_.reset(); |
| } |
| bool HistoryService::Init( |
| @@ -872,14 +882,23 @@ bool HistoryService::Init( |
| const HistoryDatabaseParams& history_database_params) { |
| TRACE_EVENT0("browser,startup", "HistoryService::Init") |
| SCOPED_UMA_HISTOGRAM_TIMER("History.HistoryServiceInitTime"); |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| + DCHECK(!backend_task_runner_); |
| - base::Thread::Options options; |
| - options.timer_slack = base::TIMER_SLACK_MAXIMUM; |
| - if (!thread_->StartWithOptions(options)) { |
| - Cleanup(); |
| - return false; |
| + if (thread_) { |
| + base::Thread::Options options; |
| + options.timer_slack = base::TIMER_SLACK_MAXIMUM; |
| + if (!thread_->StartWithOptions(options)) { |
| + Cleanup(); |
| + return false; |
| + } |
| + backend_task_runner_ = thread_->task_runner(); |
| + } else { |
| + backend_task_runner_ = base::CreateSequencedTaskRunnerWithTraits( |
| + base::TaskTraits() |
| + .WithPriority(base::TaskPriority::USER_BLOCKING) |
| + .WithShutdownBehavior(base::TaskShutdownBehavior::BLOCK_SHUTDOWN) |
| + .WithFileIO()); |
| } |
| // Create the history backend. |
| @@ -887,7 +906,7 @@ bool HistoryService::Init( |
| new BackendDelegate(weak_ptr_factory_.GetWeakPtr(), |
| base::ThreadTaskRunnerHandle::Get()), |
| history_client_ ? history_client_->CreateBackendClient() : nullptr, |
| - thread_->task_runner())); |
| + backend_task_runner_)); |
| history_backend_.swap(backend); |
| ScheduleTask(PRIORITY_UI, |
| @@ -913,10 +932,9 @@ void HistoryService::ScheduleAutocomplete( |
| void HistoryService::ScheduleTask(SchedulePriority priority, |
| const base::Closure& task) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - CHECK(thread_); |
| - CHECK(thread_->message_loop()); |
| + CHECK(backend_task_runner_); |
| // TODO(brettw): Do prioritization. |
| - thread_->task_runner()->PostTask(FROM_HERE, task); |
| + backend_task_runner_->PostTask(FROM_HERE, task); |
| } |
| base::WeakPtr<HistoryService> HistoryService::AsWeakPtr() { |
| @@ -982,7 +1000,7 @@ void HistoryService::NotifyProfileError(sql::InitStatus init_status, |
| } |
| void HistoryService::DeleteURL(const GURL& url) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| // We will update the visited links when we observe the delete notifications. |
| ScheduleTask(PRIORITY_NORMAL, base::Bind(&HistoryBackend::DeleteURL, |
| @@ -990,7 +1008,7 @@ void HistoryService::DeleteURL(const GURL& url) { |
| } |
| void HistoryService::DeleteURLsForTest(const std::vector<GURL>& urls) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| // We will update the visited links when we observe the delete |
| // notifications. |
| @@ -1004,10 +1022,10 @@ void HistoryService::ExpireHistoryBetween( |
| Time end_time, |
| const base::Closure& callback, |
| base::CancelableTaskTracker* tracker) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| tracker->PostTaskAndReply( |
| - thread_->task_runner().get(), FROM_HERE, |
| + backend_task_runner_.get(), FROM_HERE, |
| base::Bind(&HistoryBackend::ExpireHistoryBetween, history_backend_, |
| restrict_urls, begin_time, end_time), |
| callback); |
| @@ -1017,10 +1035,10 @@ void HistoryService::ExpireHistory( |
| const std::vector<ExpireHistoryArgs>& expire_list, |
| const base::Closure& callback, |
| base::CancelableTaskTracker* tracker) { |
| - DCHECK(thread_) << "History service being called after cleanup"; |
| + DCHECK(backend_task_runner_) << "History service being called after cleanup"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| tracker->PostTaskAndReply( |
| - thread_->task_runner().get(), FROM_HERE, |
| + backend_task_runner_.get(), FROM_HERE, |
| base::Bind(&HistoryBackend::ExpireHistory, history_backend_, expire_list), |
| callback); |
| } |
| @@ -1078,7 +1096,7 @@ void HistoryService::NotifyURLsDeleted(bool all_history, |
| const URLRows& deleted_rows, |
| const std::set<GURL>& favicon_urls) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - if (!thread_) |
| + if (!backend_task_runner_) |
| return; |
| // Inform the VisitDelegate of the deleted URLs. We will inform the delegate |