summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/base.gyp4
-rw-r--r--chrome/browser/net/sqlite_persistent_cookie_store.cc238
-rw-r--r--chrome/browser/net/sqlite_persistent_cookie_store.h6
-rw-r--r--chrome/browser/net/sqlite_persistent_cookie_store_perftest.cc51
-rw-r--r--chrome/browser/net/sqlite_persistent_cookie_store_unittest.cc121
-rw-r--r--chrome/browser/profiles/profile_impl_io_data.cc11
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_service.cc7
7 files changed, 235 insertions, 203 deletions
diff --git a/base/base.gyp b/base/base.gyp
index a17508a..33c334d 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -568,8 +568,6 @@
'template_util_unittest.cc',
'test/expectations/expectation_unittest.cc',
'test/expectations/parser_unittest.cc',
- 'test/sequenced_worker_pool_owner.cc',
- 'test/sequenced_worker_pool_owner.h',
'test/trace_event_analyzer_unittest.cc',
'threading/non_thread_safe_unittest.cc',
'threading/platform_thread_unittest.cc',
@@ -834,6 +832,8 @@
'test/scoped_path_override.h',
'test/sequenced_task_runner_test_template.cc',
'test/sequenced_task_runner_test_template.h',
+ 'test/sequenced_worker_pool_owner.cc',
+ 'test/sequenced_worker_pool_owner.h',
'test/simple_test_clock.cc',
'test/simple_test_clock.h',
'test/simple_test_tick_clock.cc',
diff --git a/chrome/browser/net/sqlite_persistent_cookie_store.cc b/chrome/browser/net/sqlite_persistent_cookie_store.cc
index 0d14ecf..b2d0255 100644
--- a/chrome/browser/net/sqlite_persistent_cookie_store.cc
+++ b/chrome/browser/net/sqlite_persistent_cookie_store.cc
@@ -14,17 +14,17 @@
#include "base/callback.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
+#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
+#include "base/sequenced_task_runner.h"
#include "base/string_util.h"
#include "base/synchronization/lock.h"
-#include "base/threading/thread.h"
#include "base/time.h"
#include "chrome/browser/diagnostics/sqlite_diagnostics.h"
#include "chrome/browser/net/clear_on_exit_policy.h"
-#include "content/public/browser/browser_thread.h"
#include "googleurl/src/gurl.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/cookies/canonical_cookie.h"
@@ -35,36 +35,38 @@
#include "third_party/sqlite/sqlite3.h"
using base::Time;
-using content::BrowserThread;
-// This class is designed to be shared between any calling threads and the
-// database thread. It batches operations and commits them on a timer.
+// This class is designed to be shared between any client thread and the
+// background task runner. It batches operations and commits them on a timer.
//
// SQLitePersistentCookieStore::Load is called to load all cookies. It
// delegates to Backend::Load, which posts a Backend::LoadAndNotifyOnDBThread
-// task to the DB thread. This task calls Backend::ChainLoadCookies(), which
-// repeatedly posts itself to the DB thread to load each eTLD+1's cookies in
-// separate tasks. When this is complete, Backend::CompleteLoadOnIOThread is
-// posted to the IO thread, which notifies the caller of
+// task to the background runner. This task calls Backend::ChainLoadCookies(),
+// which repeatedly posts itself to the BG runner to load each eTLD+1's cookies
+// in separate tasks. When this is complete, Backend::CompleteLoadOnIOThread is
+// posted to the client runner, which notifies the caller of
// SQLitePersistentCookieStore::Load that the load is complete.
//
// If a priority load request is invoked via SQLitePersistentCookieStore::
// LoadCookiesForKey, it is delegated to Backend::LoadCookiesForKey, which posts
-// Backend::LoadKeyAndNotifyOnDBThread to the DB thread. That routine loads just
+// Backend::LoadKeyAndNotifyOnDBThread to the BG runner. That routine loads just
// that single domain key (eTLD+1)'s cookies, and posts a Backend::
-// CompleteLoadForKeyOnIOThread to the IO thread to notify the caller of
+// CompleteLoadForKeyOnIOThread to the client runner to notify the caller of
// SQLitePersistentCookieStore::LoadCookiesForKey that that load is complete.
//
// Subsequent to loading, mutations may be queued by any thread using
// AddCookie, UpdateCookieAccessTime, and DeleteCookie. These are flushed to
-// disk on the DB thread every 30 seconds, 512 operations, or call to Flush(),
+// disk on the BG runner every 30 seconds, 512 operations, or call to Flush(),
// whichever occurs first.
class SQLitePersistentCookieStore::Backend
: public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> {
public:
- Backend(const base::FilePath& path,
- bool restore_old_session_cookies,
- ClearOnExitPolicy* clear_on_exit_policy)
+ Backend(
+ const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& client_task_runner,
+ const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
+ bool restore_old_session_cookies,
+ ClearOnExitPolicy* clear_on_exit_policy)
: path_(path),
db_(NULL),
num_pending_(0),
@@ -74,6 +76,8 @@ class SQLitePersistentCookieStore::Backend
restore_old_session_cookies_(restore_old_session_cookies),
clear_on_exit_policy_(clear_on_exit_policy),
num_cookies_read_(0),
+ client_task_runner_(client_task_runner),
+ background_task_runner_(background_task_runner),
num_priority_waiting_(0),
total_priority_requests_(0) {
}
@@ -157,14 +161,14 @@ class SQLitePersistentCookieStore::Backend
};
private:
- // Creates or loads the SQLite database on DB thread.
- void LoadAndNotifyOnDBThread(const LoadedCallback& loaded_callback,
- const base::Time& posted_at);
+ // Creates or loads the SQLite database on background runner.
+ void LoadAndNotifyInBackground(const LoadedCallback& loaded_callback,
+ const base::Time& posted_at);
- // Loads cookies for the domain key (eTLD+1) on DB thread.
- void LoadKeyAndNotifyOnDBThread(const std::string& domains,
- const LoadedCallback& loaded_callback,
- const base::Time& posted_at);
+ // Loads cookies for the domain key (eTLD+1) on background runner.
+ void LoadKeyAndNotifyInBackground(const std::string& domains,
+ const LoadedCallback& loaded_callback,
+ const base::Time& posted_at);
// Notifies the CookieMonster when loading completes for a specific domain key
// or for all domain keys. Triggers the callback and passes it all cookies
@@ -174,28 +178,28 @@ class SQLitePersistentCookieStore::Backend
// Sends notification when the entire store is loaded, and reports metrics
// for the total time to load and aggregated results from any priority loads
// that occurred.
- void CompleteLoadOnIOThread(const LoadedCallback& loaded_callback,
- bool load_success);
+ void CompleteLoadInForeground(const LoadedCallback& loaded_callback,
+ bool load_success);
// Sends notification when a single priority load completes. Updates priority
// load metric data. The data is sent only after the final load completes.
- void CompleteLoadForKeyOnIOThread(const LoadedCallback& loaded_callback,
- bool load_success);
+ void CompleteLoadForKeyInForeground(const LoadedCallback& loaded_callback,
+ bool load_success);
- // Sends all metrics, including posting a ReportMetricsOnDBThread task.
+ // Sends all metrics, including posting a ReportMetricsInBackground task.
// Called after all priority and regular loading is complete.
void ReportMetrics();
- // Sends DB-thread owned metrics (i.e., the combined duration of all DB-thread
- // tasks).
- void ReportMetricsOnDBThread();
+ // Sends background-runner owned metrics (i.e., the combined duration of all
+ // BG-runner tasks).
+ void ReportMetricsInBackground();
// Initialize the data base.
bool InitializeDatabase();
// Loads cookies for the next domain key from the DB, then either reschedules
- // itself or schedules the provided callback to run on the IO thread (if all
- // domains are loaded).
+ // itself or schedules the provided callback to run on the client runner (if
+ // all domains are loaded).
void ChainLoadCookies(const LoadedCallback& loaded_callback);
// Load all cookies for a set of domains/hosts
@@ -206,7 +210,7 @@ class SQLitePersistentCookieStore::Backend
const net::CanonicalCookie& cc);
// Commit our pending operations to the database.
void Commit();
- // Close() executed on the background thread.
+ // Close() executed on the background runner.
void InternalBackgroundClose();
void DeleteSessionCookiesOnStartup();
@@ -216,6 +220,11 @@ class SQLitePersistentCookieStore::Backend
void KillDatabase();
void ScheduleKillDatabase();
+ void PostBackgroundTask(const tracked_objects::Location& origin,
+ const base::Closure& task);
+ void PostClientTask(const tracked_objects::Location& origin,
+ const base::Closure& task);
+
base::FilePath path_;
scoped_ptr<sql::Connection> db_;
sql::MetaTable meta_table_;
@@ -229,7 +238,7 @@ class SQLitePersistentCookieStore::Backend
base::Lock lock_;
// Temporary buffer for cookies loaded from DB. Accumulates cookies to reduce
- // the number of messages sent to the IO thread. Sent back in response to
+ // the number of messages sent to the client runner. Sent back in response to
// individual load requests for domain keys or when all loading completes.
std::vector<net::CanonicalCookie*> cookies_;
@@ -254,14 +263,17 @@ class SQLitePersistentCookieStore::Backend
// Policy defining what data is deleted on shutdown.
scoped_refptr<ClearOnExitPolicy> clear_on_exit_policy_;
- // The cumulative time spent loading the cookies on the DB thread. Incremented
- // and reported from the DB thread.
+ // The cumulative time spent loading the cookies on the background runner.
+ // Incremented and reported from the background runner.
base::TimeDelta cookie_load_duration_;
- // The total number of cookies read. Incremented and reported on the DB
- // thread.
+ // The total number of cookies read. Incremented and reported on the
+ // background runner.
int num_cookies_read_;
+ scoped_refptr<base::SequencedTaskRunner> client_task_runner_;
+ scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
+
// Guards the following metrics-related properties (only accessed when
// starting/completing priority loads or completing the total load).
base::Lock metrics_lock_;
@@ -374,10 +386,9 @@ void SQLitePersistentCookieStore::Backend::Load(
const LoadedCallback& loaded_callback) {
// This function should be called only once per instance.
DCHECK(!db_.get());
- BrowserThread::PostTask(
- BrowserThread::DB, FROM_HERE,
- base::Bind(&Backend::LoadAndNotifyOnDBThread, this, loaded_callback,
- base::Time::Now()));
+ PostBackgroundTask(FROM_HERE, base::Bind(
+ &Backend::LoadAndNotifyInBackground, this,
+ loaded_callback, base::Time::Now()));
}
void SQLitePersistentCookieStore::Backend::LoadCookiesForKey(
@@ -391,17 +402,14 @@ void SQLitePersistentCookieStore::Backend::LoadCookiesForKey(
total_priority_requests_++;
}
- BrowserThread::PostTask(
- BrowserThread::DB, FROM_HERE,
- base::Bind(&Backend::LoadKeyAndNotifyOnDBThread, this,
- key,
- loaded_callback,
- base::Time::Now()));
+ PostBackgroundTask(FROM_HERE, base::Bind(
+ &Backend::LoadKeyAndNotifyInBackground,
+ this, key, loaded_callback, base::Time::Now()));
}
-void SQLitePersistentCookieStore::Backend::LoadAndNotifyOnDBThread(
+void SQLitePersistentCookieStore::Backend::LoadAndNotifyInBackground(
const LoadedCallback& loaded_callback, const base::Time& posted_at) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
IncrementTimeDelta increment(&cookie_load_duration_);
UMA_HISTOGRAM_CUSTOM_TIMES(
@@ -411,20 +419,18 @@ void SQLitePersistentCookieStore::Backend::LoadAndNotifyOnDBThread(
50);
if (!InitializeDatabase()) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread,
- this, loaded_callback, false));
+ PostClientTask(FROM_HERE, base::Bind(
+ &Backend::CompleteLoadInForeground, this, loaded_callback, false));
} else {
ChainLoadCookies(loaded_callback);
}
}
-void SQLitePersistentCookieStore::Backend::LoadKeyAndNotifyOnDBThread(
+void SQLitePersistentCookieStore::Backend::LoadKeyAndNotifyInBackground(
const std::string& key,
const LoadedCallback& loaded_callback,
const base::Time& posted_at) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
IncrementTimeDelta increment(&cookie_load_duration_);
UMA_HISTOGRAM_CUSTOM_TIMES(
@@ -445,16 +451,16 @@ void SQLitePersistentCookieStore::Backend::LoadKeyAndNotifyOnDBThread(
}
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(
- &SQLitePersistentCookieStore::Backend::CompleteLoadForKeyOnIOThread,
- this, loaded_callback, success));
+ PostClientTask(FROM_HERE, base::Bind(
+ &SQLitePersistentCookieStore::Backend::CompleteLoadForKeyInForeground,
+ this, loaded_callback, success));
}
-void SQLitePersistentCookieStore::Backend::CompleteLoadForKeyOnIOThread(
+void SQLitePersistentCookieStore::Backend::CompleteLoadForKeyInForeground(
const LoadedCallback& loaded_callback,
bool load_success) {
+ DCHECK(client_task_runner_->RunsTasksOnCurrentThread());
+
Notify(loaded_callback, load_success);
{
@@ -468,7 +474,7 @@ void SQLitePersistentCookieStore::Backend::CompleteLoadForKeyOnIOThread(
}
-void SQLitePersistentCookieStore::Backend::ReportMetricsOnDBThread() {
+void SQLitePersistentCookieStore::Backend::ReportMetricsInBackground() {
UMA_HISTOGRAM_CUSTOM_TIMES(
"Cookie.TimeLoad",
cookie_load_duration_,
@@ -477,8 +483,8 @@ void SQLitePersistentCookieStore::Backend::ReportMetricsOnDBThread() {
}
void SQLitePersistentCookieStore::Backend::ReportMetrics() {
- BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, base::Bind(
- &SQLitePersistentCookieStore::Backend::ReportMetricsOnDBThread, this));
+ PostBackgroundTask(FROM_HERE, base::Bind(
+ &SQLitePersistentCookieStore::Backend::ReportMetricsInBackground, this));
{
base::AutoLock locked(metrics_lock_);
@@ -498,7 +504,7 @@ void SQLitePersistentCookieStore::Backend::ReportMetrics() {
}
}
-void SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread(
+void SQLitePersistentCookieStore::Backend::CompleteLoadInForeground(
const LoadedCallback& loaded_callback, bool load_success) {
Notify(loaded_callback, load_success);
@@ -509,7 +515,7 @@ void SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread(
void SQLitePersistentCookieStore::Backend::Notify(
const LoadedCallback& loaded_callback,
bool load_success) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(client_task_runner_->RunsTasksOnCurrentThread());
std::vector<net::CanonicalCookie*> cookies;
{
@@ -521,7 +527,7 @@ void SQLitePersistentCookieStore::Backend::Notify(
}
bool SQLitePersistentCookieStore::Backend::InitializeDatabase() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
if (initialized_ || corruption_detected_) {
// Return false if we were previously initialized but the DB has since been
@@ -608,7 +614,7 @@ bool SQLitePersistentCookieStore::Backend::InitializeDatabase() {
void SQLitePersistentCookieStore::Backend::ChainLoadCookies(
const LoadedCallback& loaded_callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
IncrementTimeDelta increment(&cookie_load_duration_);
bool load_success = true;
@@ -625,17 +631,15 @@ void SQLitePersistentCookieStore::Backend::ChainLoadCookies(
}
// If load is successful and there are more domain keys to be loaded,
- // then post a DB task to continue chain-load;
- // Otherwise notify on IO thread.
+ // then post a background task to continue chain-load;
+ // Otherwise notify on client runner.
if (load_success && keys_to_load_.size() > 0) {
- BrowserThread::PostTask(
- BrowserThread::DB, FROM_HERE,
- base::Bind(&Backend::ChainLoadCookies, this, loaded_callback));
+ PostBackgroundTask(FROM_HERE, base::Bind(
+ &Backend::ChainLoadCookies, this, loaded_callback));
} else {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread,
- this, loaded_callback, load_success));
+ PostClientTask(FROM_HERE, base::Bind(
+ &Backend::CompleteLoadInForeground, this,
+ loaded_callback, load_success));
if (load_success && !restore_old_session_cookies_)
DeleteSessionCookiesOnStartup();
}
@@ -643,7 +647,7 @@ void SQLitePersistentCookieStore::Backend::ChainLoadCookies(
bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains(
const std::set<std::string>& domains) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
sql::Statement smt;
if (restore_old_session_cookies_) {
@@ -830,7 +834,7 @@ void SQLitePersistentCookieStore::Backend::BatchOperation(
static const int kCommitIntervalMs = 30 * 1000;
// Commit right away if we have more than 512 outstanding operations.
static const size_t kCommitAfterBatchSize = 512;
- DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB));
+ DCHECK(!background_task_runner_->RunsTasksOnCurrentThread());
// We do a full copy of the cookie here, and hopefully just here.
scoped_ptr<PendingOperation> po(new PendingOperation(op, cc));
@@ -844,20 +848,19 @@ void SQLitePersistentCookieStore::Backend::BatchOperation(
if (num_pending == 1) {
// We've gotten our first entry for this batch, fire off the timer.
- BrowserThread::PostDelayedTask(
- BrowserThread::DB, FROM_HERE,
- base::Bind(&Backend::Commit, this),
- base::TimeDelta::FromMilliseconds(kCommitIntervalMs));
+ if (!background_task_runner_->PostDelayedTask(
+ FROM_HERE, base::Bind(&Backend::Commit, this),
+ base::TimeDelta::FromMilliseconds(kCommitIntervalMs))) {
+ NOTREACHED() << "background_task_runner_ is not running.";
+ }
} else if (num_pending == kCommitAfterBatchSize) {
// We've reached a big enough batch, fire off a commit now.
- BrowserThread::PostTask(
- BrowserThread::DB, FROM_HERE,
- base::Bind(&Backend::Commit, this));
+ PostBackgroundTask(FROM_HERE, base::Bind(&Backend::Commit, this));
}
}
void SQLitePersistentCookieStore::Backend::Commit() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
PendingOperationsList ops;
{
@@ -947,33 +950,32 @@ void SQLitePersistentCookieStore::Backend::Commit() {
void SQLitePersistentCookieStore::Backend::Flush(
const base::Closure& callback) {
- DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB));
- BrowserThread::PostTask(
- BrowserThread::DB, FROM_HERE, base::Bind(&Backend::Commit, this));
+ DCHECK(!background_task_runner_->RunsTasksOnCurrentThread());
+ PostBackgroundTask(FROM_HERE, base::Bind(&Backend::Commit, this));
+
if (!callback.is_null()) {
// We want the completion task to run immediately after Commit() returns.
// Posting it from here means there is less chance of another task getting
// onto the message queue first, than if we posted it from Commit() itself.
- BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, callback);
+ PostBackgroundTask(FROM_HERE, callback);
}
}
-// Fire off a close message to the background thread. We could still have a
+// Fire off a close message to the background runner. We could still have a
// pending commit timer or Load operations holding references on us, but if/when
// this fires we will already have been cleaned up and it will be ignored.
void SQLitePersistentCookieStore::Backend::Close() {
- if (BrowserThread::CurrentlyOn(BrowserThread::DB)) {
+ if (background_task_runner_->RunsTasksOnCurrentThread()) {
InternalBackgroundClose();
} else {
- // Must close the backend on the background thread.
- BrowserThread::PostTask(
- BrowserThread::DB, FROM_HERE,
- base::Bind(&Backend::InternalBackgroundClose, this));
+ // Must close the backend on the background runner.
+ PostBackgroundTask(FROM_HERE,
+ base::Bind(&Backend::InternalBackgroundClose, this));
}
}
void SQLitePersistentCookieStore::Backend::InternalBackgroundClose() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
// Commit any pending operations
Commit();
@@ -987,7 +989,7 @@ void SQLitePersistentCookieStore::Backend::InternalBackgroundClose() {
}
void SQLitePersistentCookieStore::Backend::DeleteSessionCookiesOnShutdown() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
if (!db_.get())
return;
@@ -1028,18 +1030,17 @@ void SQLitePersistentCookieStore::Backend::DeleteSessionCookiesOnShutdown() {
}
void SQLitePersistentCookieStore::Backend::ScheduleKillDatabase() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
corruption_detected_ = true;
// Don't just do the close/delete here, as we are being called by |db| and
// that seems dangerous.
- MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&Backend::KillDatabase, this));
+ PostBackgroundTask(FROM_HERE, base::Bind(&Backend::KillDatabase, this));
}
void SQLitePersistentCookieStore::Backend::KillDatabase() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
if (db_.get()) {
// This Backend will now be in-memory only. In a future run we will recreate
@@ -1057,17 +1058,38 @@ void SQLitePersistentCookieStore::Backend::SetForceKeepSessionState() {
}
void SQLitePersistentCookieStore::Backend::DeleteSessionCookiesOnStartup() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
+ DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
if (!db_->Execute("DELETE FROM cookies WHERE persistent == 0"))
LOG(WARNING) << "Unable to delete session cookies.";
}
+void SQLitePersistentCookieStore::Backend::PostBackgroundTask(
+ const tracked_objects::Location& origin, const base::Closure& task) {
+ if (!background_task_runner_->PostTask(origin, task)) {
+ LOG(WARNING) << "Failed to post task from " << origin.ToString()
+ << " to background_task_runner_.";
+ }
+}
+
+void SQLitePersistentCookieStore::Backend::PostClientTask(
+ const tracked_objects::Location& origin, const base::Closure& task) {
+ if (!client_task_runner_->PostTask(origin, task)) {
+ LOG(WARNING) << "Failed to post task from " << origin.ToString()
+ << " to client_task_runner_.";
+ }
+}
+
SQLitePersistentCookieStore::SQLitePersistentCookieStore(
const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& client_task_runner,
+ const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
bool restore_old_session_cookies,
ClearOnExitPolicy* clear_on_exit_policy)
- : backend_(
- new Backend(path, restore_old_session_cookies, clear_on_exit_policy)) {
+ : backend_(new Backend(path,
+ client_task_runner,
+ background_task_runner,
+ restore_old_session_cookies,
+ clear_on_exit_policy)) {
}
void SQLitePersistentCookieStore::Load(const LoadedCallback& loaded_callback) {
@@ -1104,5 +1126,5 @@ void SQLitePersistentCookieStore::Flush(const base::Closure& callback) {
SQLitePersistentCookieStore::~SQLitePersistentCookieStore() {
backend_->Close();
// We release our reference to the Backend, though it will probably still have
- // a reference if the background thread has not run Close() yet.
+ // a reference if the background runner has not run Close() yet.
}
diff --git a/chrome/browser/net/sqlite_persistent_cookie_store.h b/chrome/browser/net/sqlite_persistent_cookie_store.h
index bb6206d..fae504d 100644
--- a/chrome/browser/net/sqlite_persistent_cookie_store.h
+++ b/chrome/browser/net/sqlite_persistent_cookie_store.h
@@ -20,6 +20,7 @@ class Task;
namespace base {
class FilePath;
+class SequencedTaskRunner;
}
namespace net {
@@ -36,8 +37,13 @@ class SQLitePersistentCookieStore
public:
// If non-NULL, SQLitePersistentCookieStore will keep a scoped_refptr to the
// |clear_on_exit_policy| throughout its lifetime.
+ // All blocking database accesses will be performed on
+ // |background_task_runner|, while |client_task_runner| is used to invoke
+ // callbacks.
SQLitePersistentCookieStore(
const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& client_task_runner,
+ const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
bool restore_old_session_cookies,
ClearOnExitPolicy* clear_on_exit_policy);
diff --git a/chrome/browser/net/sqlite_persistent_cookie_store_perftest.cc b/chrome/browser/net/sqlite_persistent_cookie_store_perftest.cc
index b03a14c..d48ad3f 100644
--- a/chrome/browser/net/sqlite_persistent_cookie_store_perftest.cc
+++ b/chrome/browser/net/sqlite_persistent_cookie_store_perftest.cc
@@ -3,26 +3,24 @@
// found in the LICENSE file.
#include "base/bind.h"
+#include "base/compiler_specific.h"
#include "base/files/scoped_temp_dir.h"
-#include "base/message_loop.h"
#include "base/perftimer.h"
+#include "base/sequenced_task_runner.h"
#include "base/stringprintf.h"
#include "base/synchronization/waitable_event.h"
-#include "base/test/thread_test_helper.h"
+#include "base/test/sequenced_worker_pool_owner.h"
+#include "base/threading/sequenced_worker_pool.h"
#include "chrome/browser/net/sqlite_persistent_cookie_store.h"
#include "chrome/common/chrome_constants.h"
-#include "content/public/test/test_browser_thread.h"
#include "googleurl/src/gurl.h"
#include "net/cookies/canonical_cookie.h"
#include "testing/gtest/include/gtest/gtest.h"
-using content::BrowserThread;
-
class SQLitePersistentCookieStorePerfTest : public testing::Test {
public:
SQLitePersistentCookieStorePerfTest()
- : db_thread_(BrowserThread::DB),
- io_thread_(BrowserThread::IO),
+ : pool_owner_(new base::SequencedWorkerPoolOwner(1, "Background Pool")),
loaded_event_(false, false),
key_loaded_event_(false, false) {
}
@@ -43,12 +41,22 @@ class SQLitePersistentCookieStorePerfTest : public testing::Test {
loaded_event_.Wait();
}
- virtual void SetUp() {
- db_thread_.Start();
- io_thread_.Start();
+ scoped_refptr<base::SequencedTaskRunner> background_task_runner() {
+ return pool_owner_->pool()->GetSequencedTaskRunner(
+ pool_owner_->pool()->GetNamedSequenceToken("background"));
+ }
+
+ scoped_refptr<base::SequencedTaskRunner> client_task_runner() {
+ return pool_owner_->pool()->GetSequencedTaskRunner(
+ pool_owner_->pool()->GetNamedSequenceToken("client"));
+ }
+
+ virtual void SetUp() OVERRIDE {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
store_ = new SQLitePersistentCookieStore(
temp_dir_.path().Append(chrome::kCookieFilename),
+ client_task_runner(),
+ background_task_runner(),
false, NULL);
std::vector<net::CanonicalCookie*> cookies;
Load();
@@ -70,19 +78,26 @@ class SQLitePersistentCookieStorePerfTest : public testing::Test {
// Replace the store effectively destroying the current one and forcing it
// to write its data to disk.
store_ = NULL;
- scoped_refptr<base::ThreadTestHelper> helper(
- new base::ThreadTestHelper(
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)));
- // Make sure we wait until the destructor has run.
- ASSERT_TRUE(helper->Run());
+
+ // Shut down the pool, causing deferred (no-op) commits to be discarded.
+ pool_owner_->pool()->Shutdown();
+ // ~SequencedWorkerPoolOwner blocks on pool shutdown.
+ pool_owner_.reset(new base::SequencedWorkerPoolOwner(1, "pool"));
store_ = new SQLitePersistentCookieStore(
- temp_dir_.path().Append(chrome::kCookieFilename), false, NULL);
+ temp_dir_.path().Append(chrome::kCookieFilename),
+ client_task_runner(),
+ background_task_runner(),
+ false, NULL);
+ }
+
+ virtual void TearDown() OVERRIDE {
+ store_ = NULL;
+ pool_owner_->pool()->Shutdown();
}
protected:
- content::TestBrowserThread db_thread_;
- content::TestBrowserThread io_thread_;
+ scoped_ptr<base::SequencedWorkerPoolOwner> pool_owner_;
base::WaitableEvent loaded_event_;
base::WaitableEvent key_loaded_event_;
std::vector<net::CanonicalCookie*> cookies_;
diff --git a/chrome/browser/net/sqlite_persistent_cookie_store_unittest.cc b/chrome/browser/net/sqlite_persistent_cookie_store_unittest.cc
index 4744d75..7569599 100644
--- a/chrome/browser/net/sqlite_persistent_cookie_store_unittest.cc
+++ b/chrome/browser/net/sqlite_persistent_cookie_store_unittest.cc
@@ -11,14 +11,15 @@
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
+#include "base/sequenced_task_runner.h"
#include "base/stl_util.h"
#include "base/synchronization/waitable_event.h"
-#include "base/test/thread_test_helper.h"
+#include "base/test/sequenced_worker_pool_owner.h"
+#include "base/threading/sequenced_worker_pool.h"
#include "base/time.h"
#include "chrome/browser/net/clear_on_exit_policy.h"
#include "chrome/browser/net/sqlite_persistent_cookie_store.h"
#include "chrome/common/chrome_constants.h"
-#include "content/public/test/test_browser_thread.h"
#include "googleurl/src/gurl.h"
#include "net/cookies/canonical_cookie.h"
#include "sql/connection.h"
@@ -26,16 +27,12 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/quota/mock_special_storage_policy.h"
-using content::BrowserThread;
-
typedef std::vector<net::CanonicalCookie*> CanonicalCookieVector;
class SQLitePersistentCookieStoreTest : public testing::Test {
public:
SQLitePersistentCookieStoreTest()
- : ui_thread_(BrowserThread::UI),
- db_thread_(BrowserThread::DB),
- io_thread_(BrowserThread::IO),
+ : pool_owner_(new base::SequencedWorkerPoolOwner(3, "Background Pool")),
loaded_event_(false, false),
key_loaded_event_(false, false),
db_thread_event_(false, false) {
@@ -52,26 +49,46 @@ class SQLitePersistentCookieStoreTest : public testing::Test {
}
void Load(CanonicalCookieVector* cookies) {
+ EXPECT_FALSE(loaded_event_.IsSignaled());
store_->Load(base::Bind(&SQLitePersistentCookieStoreTest::OnLoaded,
base::Unretained(this)));
loaded_event_.Wait();
*cookies = cookies_;
}
+ void Flush() {
+ base::WaitableEvent event(false, false);
+ store_->Flush(base::Bind(&base::WaitableEvent::Signal,
+ base::Unretained(&event)));
+ event.Wait();
+ }
+
+ scoped_refptr<base::SequencedTaskRunner> background_task_runner() {
+ return pool_owner_->pool()->GetSequencedTaskRunner(
+ pool_owner_->pool()->GetNamedSequenceToken("background"));
+ }
+
+ scoped_refptr<base::SequencedTaskRunner> client_task_runner() {
+ return pool_owner_->pool()->GetSequencedTaskRunner(
+ pool_owner_->pool()->GetNamedSequenceToken("client"));
+ }
+
void DestroyStore() {
store_ = NULL;
- // Make sure we wait until the destructor has run by waiting for all pending
- // tasks on the DB thread to run.
- scoped_refptr<base::ThreadTestHelper> helper(
- new base::ThreadTestHelper(
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)));
- ASSERT_TRUE(helper->Run());
+ // Make sure we wait until the destructor has run by shutting down the pool
+ // resetting the owner (whose destructor blocks on the pool completion).
+ pool_owner_->pool()->Shutdown();
+ // Create a new pool for the few tests that create multiple stores. In other
+ // cases this is wasted but harmless.
+ pool_owner_.reset(new base::SequencedWorkerPoolOwner(3, "Background Pool"));
}
void CreateAndLoad(bool restore_old_session_cookies,
CanonicalCookieVector* cookies) {
store_ = new SQLitePersistentCookieStore(
temp_dir_.path().Append(chrome::kCookieFilename),
+ client_task_runner(),
+ background_task_runner(),
restore_old_session_cookies,
NULL);
Load(cookies);
@@ -80,7 +97,7 @@ class SQLitePersistentCookieStoreTest : public testing::Test {
void InitializeStore(bool restore_old_session_cookies) {
CanonicalCookieVector cookies;
CreateAndLoad(restore_old_session_cookies, &cookies);
- ASSERT_EQ(0U, cookies.size());
+ EXPECT_EQ(0U, cookies.size());
}
// We have to create this method to wrap WaitableEvent::Wait, since we cannot
@@ -101,17 +118,18 @@ class SQLitePersistentCookieStoreTest : public testing::Test {
false));
}
- virtual void SetUp() {
- ui_thread_.Start();
- db_thread_.Start();
- io_thread_.Start();
+ virtual void SetUp() OVERRIDE {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
}
+ virtual void TearDown() OVERRIDE {
+ DestroyStore();
+ pool_owner_->pool()->Shutdown();
+ }
+
protected:
- content::TestBrowserThread ui_thread_;
- content::TestBrowserThread db_thread_;
- content::TestBrowserThread io_thread_;
+ MessageLoop main_loop_;
+ scoped_ptr<base::SequencedWorkerPoolOwner> pool_owner_;
base::WaitableEvent loaded_event_;
base::WaitableEvent key_loaded_event_;
base::WaitableEvent db_thread_event_;
@@ -201,11 +219,14 @@ TEST_F(SQLitePersistentCookieStoreTest, TestLoadCookiesForKey) {
DestroyStore();
store_ = new SQLitePersistentCookieStore(
- temp_dir_.path().Append(chrome::kCookieFilename), false, NULL);
+ temp_dir_.path().Append(chrome::kCookieFilename),
+ client_task_runner(),
+ background_task_runner(),
+ false, NULL);
// Posting a blocking task to db_thread_ makes sure that the DB thread waits
// until both Load and LoadCookiesForKey have been posted to its task queue.
- BrowserThread::PostTask(
- BrowserThread::DB, FROM_HERE,
+ background_task_runner()->PostTask(
+ FROM_HERE,
base::Bind(&SQLitePersistentCookieStoreTest::WaitOnDBEvent,
base::Unretained(this)));
store_->Load(base::Bind(&SQLitePersistentCookieStoreTest::OnLoaded,
@@ -213,8 +234,8 @@ TEST_F(SQLitePersistentCookieStoreTest, TestLoadCookiesForKey) {
store_->LoadCookiesForKey("aaa.com",
base::Bind(&SQLitePersistentCookieStoreTest::OnKeyLoaded,
base::Unretained(this)));
- BrowserThread::PostTask(
- BrowserThread::DB, FROM_HERE,
+ background_task_runner()->PostTask(
+ FROM_HERE,
base::Bind(&SQLitePersistentCookieStoreTest::WaitOnDBEvent,
base::Unretained(this)));
@@ -273,59 +294,13 @@ TEST_F(SQLitePersistentCookieStoreTest, TestFlush) {
AddCookie(name, value, "foo.bar", "/", t);
}
- // Call Flush() and wait until the DB thread is idle.
- store_->Flush(base::Closure());
- scoped_refptr<base::ThreadTestHelper> helper(
- new base::ThreadTestHelper(
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)));
- ASSERT_TRUE(helper->Run());
+ Flush();
// We forced a write, so now the file will be bigger.
ASSERT_TRUE(file_util::GetFileInfo(path, &info));
ASSERT_GT(info.size, base_size);
}
-// Counts the number of times Callback() has been run.
-class CallbackCounter : public base::RefCountedThreadSafe<CallbackCounter> {
- public:
- CallbackCounter() : callback_count_(0) {}
-
- void Callback() {
- ++callback_count_;
- }
-
- int callback_count() {
- return callback_count_;
- }
-
- private:
- friend class base::RefCountedThreadSafe<CallbackCounter>;
- ~CallbackCounter() {}
-
- volatile int callback_count_;
-};
-
-// Test that we can get a completion callback after a Flush().
-TEST_F(SQLitePersistentCookieStoreTest, TestFlushCompletionCallback) {
- InitializeStore(false);
- // Put some data - any data - on disk, so that Flush is not a no-op.
- AddCookie("A", "B", "foo.bar", "/", base::Time::Now());
-
- scoped_refptr<CallbackCounter> counter(new CallbackCounter());
-
- // Callback shouldn't be invoked until we call Flush().
- ASSERT_EQ(0, counter->callback_count());
-
- store_->Flush(base::Bind(&CallbackCounter::Callback, counter.get()));
-
- scoped_refptr<base::ThreadTestHelper> helper(
- new base::ThreadTestHelper(
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)));
- ASSERT_TRUE(helper->Run());
-
- ASSERT_EQ(1, counter->callback_count());
-}
-
// Test loading old session cookies from the disk.
TEST_F(SQLitePersistentCookieStoreTest, TestLoadOldSessionCookies) {
InitializeStore(true);
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc
index ac66d6a..0535f10 100644
--- a/chrome/browser/profiles/profile_impl_io_data.cc
+++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -388,6 +388,8 @@ void ProfileImplIOData::InitializeInternal(
scoped_refptr<SQLitePersistentCookieStore> cookie_db =
new SQLitePersistentCookieStore(
lazy_params_->cookie_path,
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB),
lazy_params_->restore_old_session_cookies,
new ClearOnExitPolicy(lazy_params_->special_storage_policy));
cookie_store =
@@ -496,6 +498,8 @@ void ProfileImplIOData::
new net::CookieMonster(
new SQLitePersistentCookieStore(
lazy_params_->extensions_cookie_path,
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB),
lazy_params_->restore_old_session_cookies, NULL), NULL);
// Enable cookies for devtools and extension URLs.
const char* schemes[] = {chrome::kChromeDevToolsScheme,
@@ -592,7 +596,12 @@ ProfileImplIOData::InitializeAppRequestContext(
DCHECK(!cookie_path.empty());
scoped_refptr<SQLitePersistentCookieStore> cookie_db =
- new SQLitePersistentCookieStore(cookie_path, false, NULL);
+ new SQLitePersistentCookieStore(
+ cookie_path,
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB),
+ false,
+ NULL);
// TODO(creis): We should have a cookie delegate for notifying the cookie
// extensions API, but we need to update it to understand isolated apps
// first.
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc
index 24b8453..afd0ca5 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -305,7 +305,12 @@ void SafeBrowsingService::InitURLRequestContextOnIOThread(
DCHECK(!url_request_context_.get());
scoped_refptr<net::CookieStore> cookie_store = new net::CookieMonster(
- new SQLitePersistentCookieStore(CookieFilePath(), false, NULL),
+ new SQLitePersistentCookieStore(
+ CookieFilePath(),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB),
+ false,
+ NULL),
NULL);
url_request_context_.reset(new net::URLRequestContext);