Index: chrome/browser/net/sqlite_persistent_cookie_store.cc |
=================================================================== |
--- chrome/browser/net/sqlite_persistent_cookie_store.cc (revision 95998) |
+++ chrome/browser/net/sqlite_persistent_cookie_store.cc (working copy) |
@@ -7,6 +7,7 @@ |
#include <list> |
#include "base/basictypes.h" |
+#include "base/bind.h" |
#include "base/file_path.h" |
#include "base/file_util.h" |
#include "base/logging.h" |
@@ -38,7 +39,7 @@ |
} |
// Creates or load the SQLite database. |
- bool Load(std::vector<net::CookieMonster::CanonicalCookie*>* cookies); |
+ bool Load(const LoadedCallback& loaded_callback); |
// Batch a cookie addition. |
void AddCookie(const net::CookieMonster::CanonicalCookie& cc); |
@@ -91,6 +92,11 @@ |
}; |
private: |
+ // Creates or load the SQLite database on DB thread. |
+ void LoadOnDBThread(); |
+ // Notify the CookieMonster when loading complete. |
+ void Notify(bool load_success_); |
+ |
// Batch a cookie operation (add or delete) |
void BatchOperation(PendingOperation::OperationType op, |
const net::CookieMonster::CanonicalCookie& cc); |
@@ -103,6 +109,9 @@ |
scoped_ptr<sql::Connection> db_; |
sql::MetaTable meta_table_; |
+ std::vector<net::CookieMonster::CanonicalCookie*> cookies_; |
+ LoadedCallback loaded_callback_; |
+ |
typedef std::list<PendingOperation*> PendingOperationsList; |
PendingOperationsList pending_; |
PendingOperationsList::size_type num_pending_; |
@@ -154,26 +163,37 @@ |
} // namespace |
bool SQLitePersistentCookieStore::Backend::Load( |
- std::vector<net::CookieMonster::CanonicalCookie*>* cookies) { |
+ const LoadedCallback& loaded_callback) { |
// This function should be called only once per instance. |
DCHECK(!db_.get()); |
+ loaded_callback_ = loaded_callback; |
erikwright (departed)
2011/08/11 15:13:52
DCHECK(loaded_callback_.is_null());
ycxiao
2011/08/12 02:35:24
Done.
|
+ BrowserThread::PostTask( |
+ BrowserThread::DB, FROM_HERE, |
+ base::Bind(&Backend::LoadOnDBThread, base::Unretained(this))); |
+ return true; |
+} |
+void SQLitePersistentCookieStore::Backend::LoadOnDBThread() { |
erikwright (departed)
2011/08/11 15:13:52
Write LoadAndNotifyOnDBThread that does Notify(Loa
ycxiao
2011/08/12 02:35:24
Done.
|
// Ensure the parent directory for storing cookies is created before reading |
erikwright (departed)
2011/08/11 15:13:52
Comment is now out of date.
ycxiao
2011/08/12 02:35:24
Done.
|
// from it. We make an exception to allow IO on the UI thread here because |
// we are going to disk anyway in db_->Open. (This code will be moved to the |
// DB thread as part of http://crbug.com/52909.) |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
{ |
base::ThreadRestrictions::ScopedAllowIO allow_io; |
erikwright (departed)
2011/08/11 15:13:52
ScopedAllowIO, no longer required. Move other code
ycxiao
2011/08/12 02:35:24
Done.
|
const FilePath dir = path_.DirName(); |
- if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) |
- return false; |
+ if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) { |
+ Notify(false); |
+ return; |
+ } |
} |
db_.reset(new sql::Connection); |
if (!db_->Open(path_)) { |
NOTREACHED() << "Unable to open cookie DB."; |
db_.reset(); |
- return false; |
+ Notify(false); |
+ return; |
} |
db_->set_error_delegate(GetErrorHandlerForCookieDb()); |
@@ -181,7 +201,8 @@ |
if (!EnsureDatabaseVersion() || !InitTable(db_.get())) { |
NOTREACHED() << "Unable to open cookie DB."; |
db_.reset(); |
- return false; |
+ Notify(false); |
+ return; |
} |
db_->Preload(); |
erikwright (departed)
2011/08/11 15:13:52
Lines 184-208 should be a helper method like 'Init
ycxiao
2011/08/12 02:35:24
Done.
|
@@ -193,9 +214,15 @@ |
if (!smt) { |
NOTREACHED() << "select statement prep failed"; |
db_.reset(); |
- return false; |
+ Notify(false); |
+ return; |
} |
+ // Reserve space for the maximum amount of cookies a database should have. |
+ // This prevents multiple vector growth / copies as we append cookies. |
+ const size_t kMaxCookies = 3300; |
+ cookies_.reserve(kMaxCookies); |
+ |
while (smt.Step()) { |
scoped_ptr<net::CookieMonster::CanonicalCookie> cc( |
new net::CookieMonster::CanonicalCookie( |
@@ -215,12 +242,24 @@ |
true)); // has_expires |
DLOG_IF(WARNING, |
cc->CreationDate() > Time::Now()) << L"CreationDate too recent"; |
- cookies->push_back(cc.release()); |
+ cookies_.push_back(cc.release()); |
} |
- return true; |
+ Notify(true); |
} |
+void SQLitePersistentCookieStore::Backend::Notify(bool load_success) { |
erikwright (departed)
2011/08/11 15:13:52
It seems the success value is not used? Remove it?
ycxiao
2011/08/12 02:35:24
I also notice that it is not used. But this flag p
|
+ if (BrowserThread::CurrentlyOn(BrowserThread::DB)) { |
erikwright (departed)
2011/08/11 15:13:52
Instead of having a thread switch here, you can si
ycxiao
2011/08/12 02:35:24
Done.
|
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(&SQLitePersistentCookieStore::Backend::Notify, |
+ base::Unretained(this), load_success)); |
+ return; |
+ } |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ loaded_callback_.Run(cookies_); |
+} |
+ |
bool SQLitePersistentCookieStore::Backend::EnsureDatabaseVersion() { |
// Version check. |
if (!meta_table_.Init( |
@@ -483,9 +522,8 @@ |
} |
} |
-bool SQLitePersistentCookieStore::Load( |
- std::vector<net::CookieMonster::CanonicalCookie*>* cookies) { |
- return backend_->Load(cookies); |
+bool SQLitePersistentCookieStore::Load(const LoadedCallback& loaded_callback) { |
+ return backend_->Load(loaded_callback); |
} |
void SQLitePersistentCookieStore::AddCookie( |