summaryrefslogtreecommitdiffstats
path: root/chrome/browser/profile.cc
diff options
context:
space:
mode:
authortony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-17 21:15:37 +0000
committertony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-17 21:15:37 +0000
commit4038e6e270171286189b2cd54fcb45a7e9c08222 (patch)
tree6d81b87f94cc47483dd372a689d7bfa2091f2aba /chrome/browser/profile.cc
parent992f8306de28201f9c5253ceb3f7b1fa6e400cd7 (diff)
downloadchromium_src-4038e6e270171286189b2cd54fcb45a7e9c08222.zip
chromium_src-4038e6e270171286189b2cd54fcb45a7e9c08222.tar.gz
chromium_src-4038e6e270171286189b2cd54fcb45a7e9c08222.tar.bz2
Preload the visited link db on the file thread if the file exists.
Otherwise, just load like normal on the UI thread. BUG=24163 Review URL: http://codereview.chromium.org/502005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34874 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/profile.cc')
-rw-r--r--chrome/browser/profile.cc105
1 files changed, 95 insertions, 10 deletions
diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc
index 111029b..e61ae5a 100644
--- a/chrome/browser/profile.cc
+++ b/chrome/browser/profile.cc
@@ -125,6 +125,87 @@ bool HasACacheSubdir(const FilePath &dir) {
} // namespace
+// This helper class owns the VisitedLinkMaster and exposes a way to load it
+// from on the file thread.
+class VisitedLinkCreator
+ : public base::RefCountedThreadSafe<VisitedLinkCreator> {
+ public:
+ enum LoadState {
+ NOT_LOADED,
+ FILE_LOAD_FAILED,
+ LOAD_FINISHED
+ };
+
+ explicit VisitedLinkCreator(Profile* profile)
+ : listener_(new VisitedLinkEventListener()),
+ profile_(profile),
+ load_state_(NOT_LOADED) {
+ visited_link_master_.reset(new VisitedLinkMaster(listener_.get(),
+ profile_));
+ }
+
+ // Preload the visited link master on the file thread.
+ void Preload() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, NewRunnableMethod(
+ this, &VisitedLinkCreator::LoadBackground));
+ }
+
+ // This method can return NULL if for some reason we can't initialize the
+ // visited link master.
+ VisitedLinkMaster* GetMaster() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ // Go ahead and try to load the VisitedLink table. If the data was
+ // preloaded, Load() does nothing.
+ AutoLock l(lock_);
+ if (LOAD_FINISHED != load_state_) {
+ bool success = false;
+ if (FILE_LOAD_FAILED == load_state_) {
+ success = visited_link_master_->InitFromScratch();
+ } else if (NOT_LOADED == load_state_) {
+ // We haven't tried to load from file yet, so go ahead and do that.
+ success = visited_link_master_->Init();
+ }
+
+ if (!success) {
+ NOTREACHED() << "Failed to init visited link master.";
+ visited_link_master_.reset();
+ }
+ load_state_ = LOAD_FINISHED;
+ }
+
+ // We don't need to lock here because after Load() has been called, we
+ // never change vistied_link_master_.
+ return visited_link_master_.get();
+ }
+
+ private:
+ // Tries to load the visited link database from the UI thread.
+ void LoadBackground() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
+ AutoLock l(lock_);
+ if (NOT_LOADED != load_state_)
+ return;
+
+ // We only want to try to load the data from a file (it's not thread safe
+ // to InitFromScratch on the file thread).
+ load_state_ = visited_link_master_->InitFromFile() ? LOAD_FINISHED
+ : FILE_LOAD_FAILED;
+ }
+
+ scoped_ptr<VisitedLinkMaster::Listener> listener_;
+ Profile* profile_;
+
+ // This lock protects visited_link_master_ and load_state_.
+ Lock lock_;
+ scoped_ptr<VisitedLinkMaster> visited_link_master_;
+ // Once created_ is true, we can stop trying to create and init the
+ // VisitedLinkMaster.
+ LoadState load_state_;
+
+ DISALLOW_COPY_AND_ASSIGN(VisitedLinkCreator);
+};
+
// A pointer to the request context for the default profile. See comments on
// Profile::GetDefaultRequestContext.
URLRequestContextGetter* Profile::default_request_context_;
@@ -214,7 +295,9 @@ class OffTheRecordProfileImpl : public Profile,
return reinterpret_cast<ProfileId>(this);
}
- virtual FilePath GetPath() { return profile_->GetPath(); }
+ virtual FilePath GetPath() {
+ return profile_->GetPath();
+ }
virtual bool IsOffTheRecord() {
return true;
@@ -245,6 +328,8 @@ class OffTheRecordProfileImpl : public Profile,
return NULL;
}
+ virtual void PreloadVisitedLinkMaster() {}
+
virtual ExtensionsService* GetExtensionsService() {
return NULL;
}
@@ -567,7 +652,6 @@ class OffTheRecordProfileImpl : public Profile,
ProfileImpl::ProfileImpl(const FilePath& path)
: path_(path),
- visited_link_event_listener_(new VisitedLinkEventListener()),
extension_devtools_manager_(NULL),
request_context_(NULL),
media_request_context_(NULL),
@@ -814,15 +898,16 @@ webkit_database::DatabaseTracker* ProfileImpl::GetDatabaseTracker() {
}
VisitedLinkMaster* ProfileImpl::GetVisitedLinkMaster() {
- if (!visited_link_master_.get()) {
- scoped_ptr<VisitedLinkMaster> visited_links(
- new VisitedLinkMaster(visited_link_event_listener_.get(), this));
- if (!visited_links->Init())
- return NULL;
- visited_link_master_.swap(visited_links);
- }
+ if (!visited_link_creator_.get())
+ visited_link_creator_ = new VisitedLinkCreator(this);
+ return visited_link_creator_->GetMaster();
+}
- return visited_link_master_.get();
+void ProfileImpl::PreloadVisitedLinkMaster() {
+ if (!visited_link_creator_.get()) {
+ visited_link_creator_ = new VisitedLinkCreator(this);
+ visited_link_creator_->Preload();
+ }
}
ExtensionsService* ProfileImpl::GetExtensionsService() {