Index: chrome/browser/history/history_service.cc |
diff --git a/chrome/browser/history/history_service.cc b/chrome/browser/history/history_service.cc |
index e84d4e04778f9a8e3d5fe77f2ea8ec11c4133f9c..e393d12fdf8eff4b628426ab68deffaacd0aed07 100644 |
--- a/chrome/browser/history/history_service.cc |
+++ b/chrome/browser/history/history_service.cc |
@@ -231,63 +231,6 @@ bool HistoryService::BackendLoaded() { |
return backend_loaded_; |
} |
-void HistoryService::Cleanup() { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- if (!thread_) { |
- // We've already cleaned up. |
- return; |
- } |
- |
- weak_ptr_factory_.InvalidateWeakPtrs(); |
- |
- // Unload the backend. |
- if (history_backend_.get()) { |
- // Get rid of the in-memory backend. |
- in_memory_backend_.reset(); |
- |
- // Give the InMemoryURLIndex a chance to shutdown. |
- // NOTE: In tests, there may be no index. |
- if (in_memory_url_index_) |
- in_memory_url_index_->ShutDown(); |
- |
- // The backend's destructor must run on the history thread since it is not |
- // threadsafe. So this thread must not be the last thread holding a |
- // reference to the backend, or a crash could happen. |
- // |
- // We have a reference to the history backend. There is also an extra |
- // reference held by our delegate installed in the backend, which |
- // HistoryBackend::Closing will release. This means if we scheduled a call |
- // to HistoryBackend::Closing and *then* released our backend reference, |
- // there will be a race between us and the backend's Closing function to see |
- // who is the last holder of a reference. If the backend thread's Closing |
- // manages to run before we release our backend refptr, the last reference |
- // will be held by this thread and the destructor will be called from here. |
- // |
- // Therefore, we create a closure to run the Closing operation first. This |
- // holds a reference to the backend. Then we release our reference, then we |
- // schedule the task to run. After the task runs, it will delete its |
- // reference from the history thread, ensuring everything works properly. |
- // |
- // TODO(ajwong): Cleanup HistoryBackend lifetime issues. |
- // See http://crbug.com/99767. |
- history_backend_->AddRef(); |
- base::Closure closing_task = |
- base::Bind(&HistoryBackend::Closing, history_backend_.get()); |
- ScheduleTask(PRIORITY_NORMAL, closing_task); |
- closing_task.Reset(); |
- HistoryBackend* raw_ptr = history_backend_.get(); |
- history_backend_ = NULL; |
- thread_->message_loop()->ReleaseSoon(FROM_HERE, raw_ptr); |
- } |
- |
- // Delete the thread, which joins with the background thread. We defensively |
- // NULL the pointer before deleting it in case somebody tries to use it |
- // during shutdown, but this shouldn't happen. |
- base::Thread* thread = thread_; |
- thread_ = NULL; |
- delete thread; |
-} |
- |
void HistoryService::ClearCachedDataForContextID( |
history::ContextID context_id) { |
DCHECK(thread_) << "History service being called after cleanup"; |
@@ -903,6 +846,63 @@ base::CancelableTaskTracker::TaskId HistoryService::QueryFilteredURLs( |
base::Bind(callback, base::Owned(result))); |
} |
+void HistoryService::Cleanup() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ if (!thread_) { |
+ // We've already cleaned up. |
+ return; |
+ } |
+ |
+ weak_ptr_factory_.InvalidateWeakPtrs(); |
+ |
+ // Unload the backend. |
+ if (history_backend_.get()) { |
+ // Get rid of the in-memory backend. |
+ in_memory_backend_.reset(); |
+ |
+ // Give the InMemoryURLIndex a chance to shutdown. |
+ // NOTE: In tests, there may be no index. |
+ if (in_memory_url_index_) |
+ in_memory_url_index_->ShutDown(); |
+ |
+ // The backend's destructor must run on the history thread since it is not |
+ // threadsafe. So this thread must not be the last thread holding a |
+ // reference to the backend, or a crash could happen. |
+ // |
+ // We have a reference to the history backend. There is also an extra |
+ // reference held by our delegate installed in the backend, which |
+ // HistoryBackend::Closing will release. This means if we scheduled a call |
+ // to HistoryBackend::Closing and *then* released our backend reference, |
+ // there will be a race between us and the backend's Closing function to see |
+ // who is the last holder of a reference. If the backend thread's Closing |
+ // manages to run before we release our backend refptr, the last reference |
+ // will be held by this thread and the destructor will be called from here. |
+ // |
+ // Therefore, we create a closure to run the Closing operation first. This |
+ // holds a reference to the backend. Then we release our reference, then we |
+ // schedule the task to run. After the task runs, it will delete its |
+ // reference from the history thread, ensuring everything works properly. |
+ // |
+ // TODO(ajwong): Cleanup HistoryBackend lifetime issues. |
+ // See http://crbug.com/99767. |
+ history_backend_->AddRef(); |
+ base::Closure closing_task = |
+ base::Bind(&HistoryBackend::Closing, history_backend_.get()); |
+ ScheduleTask(PRIORITY_NORMAL, closing_task); |
+ closing_task.Reset(); |
+ HistoryBackend* raw_ptr = history_backend_.get(); |
+ history_backend_ = NULL; |
+ thread_->message_loop()->ReleaseSoon(FROM_HERE, raw_ptr); |
+ } |
+ |
+ // Delete the thread, which joins with the background thread. We defensively |
+ // NULL the pointer before deleting it in case somebody tries to use it |
+ // during shutdown, but this shouldn't happen. |
+ base::Thread* thread = thread_; |
+ thread_ = NULL; |
+ delete thread; |
+} |
+ |
void HistoryService::Observe(int type, |
const content::NotificationSource& source, |
const content::NotificationDetails& details) { |