summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/sync/engine/model_safe_worker.h5
-rw-r--r--chrome/browser/sync/engine/syncer_thread_unittest.cc4
-rwxr-xr-xchrome/browser/sync/engine/syncer_unittest.cc4
-rw-r--r--chrome/browser/sync/glue/database_model_worker.cc36
-rw-r--r--chrome/browser/sync/glue/database_model_worker.h33
-rw-r--r--chrome/browser/sync/glue/database_model_worker_unittest.cc90
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.cc16
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.h9
-rw-r--r--chrome/browser/sync/glue/ui_model_worker_unittest.cc9
-rwxr-xr-xchrome/chrome_browser.gypi2
-rwxr-xr-xchrome/chrome_tests.gypi1
11 files changed, 185 insertions, 24 deletions
diff --git a/chrome/browser/sync/engine/model_safe_worker.h b/chrome/browser/sync/engine/model_safe_worker.h
index c68218c..84a6a2f 100644
--- a/chrome/browser/sync/engine/model_safe_worker.h
+++ b/chrome/browser/sync/engine/model_safe_worker.h
@@ -8,6 +8,7 @@
#include <map>
#include <vector>
+#include "base/ref_counted.h"
#include "chrome/browser/sync/syncable/model_type.h"
#include "chrome/browser/sync/util/closure.h"
#include "chrome/browser/sync/util/sync_types.h"
@@ -30,7 +31,7 @@ enum ModelSafeGroup {
// is guaranteed to be "model-safe", where "safe" refers to not allowing us to
// cause an embedding application model to fall out of sync with the
// syncable::Directory due to a race.
-class ModelSafeWorker {
+class ModelSafeWorker : public base::RefCountedThreadSafe<ModelSafeWorker> {
public:
ModelSafeWorker() { }
virtual ~ModelSafeWorker() { }
@@ -47,6 +48,8 @@ class ModelSafeWorker {
}
private:
+ friend class base::RefCountedThreadSafe<ModelSafeWorker>;
+
DISALLOW_COPY_AND_ASSIGN(ModelSafeWorker);
};
diff --git a/chrome/browser/sync/engine/syncer_thread_unittest.cc b/chrome/browser/sync/engine/syncer_thread_unittest.cc
index 314237a..f676cd6 100644
--- a/chrome/browser/sync/engine/syncer_thread_unittest.cc
+++ b/chrome/browser/sync/engine/syncer_thread_unittest.cc
@@ -35,7 +35,7 @@ class SyncerThreadWithSyncerTest : public testing::Test,
connection_.reset(new MockConnectionManager(metadb_.manager(),
metadb_.name()));
allstatus_.reset(new AllStatus());
- worker_.reset(new ModelSafeWorker());
+ worker_ = new ModelSafeWorker();
SyncSessionContext* context = new SyncSessionContext(connection_.get(),
metadb_.manager(), this);
syncer_thread_ = new SyncerThread(context, allstatus_.get());
@@ -85,7 +85,7 @@ class SyncerThreadWithSyncerTest : public testing::Test,
scoped_ptr<MockConnectionManager> connection_;
scoped_ptr<AllStatus> allstatus_;
scoped_refptr<SyncerThread> syncer_thread_;
- scoped_ptr<ModelSafeWorker> worker_;
+ scoped_refptr<ModelSafeWorker> worker_;
scoped_ptr<EventListenerHookup> syncer_event_hookup_;
base::WaitableEvent sync_cycle_ended_event_;
DISALLOW_COPY_AND_ASSIGN(SyncerThreadWithSyncerTest);
diff --git a/chrome/browser/sync/engine/syncer_unittest.cc b/chrome/browser/sync/engine/syncer_unittest.cc
index 7d2aa38..2177e5b 100755
--- a/chrome/browser/sync/engine/syncer_unittest.cc
+++ b/chrome/browser/sync/engine/syncer_unittest.cc
@@ -166,7 +166,7 @@ class SyncerTest : public testing::Test,
mock_server_.reset(
new MockConnectionManager(syncdb_.manager(), syncdb_.name()));
- worker_.reset(new ModelSafeWorker());
+ worker_ = new ModelSafeWorker();
context_.reset(new SyncSessionContext(mock_server_.get(), syncdb_.manager(),
this));
context_->set_account_name(syncdb_.name());
@@ -399,7 +399,7 @@ class SyncerTest : public testing::Test,
std::set<SyncerEvent> syncer_events_;
base::TimeDelta last_short_poll_interval_received_;
base::TimeDelta last_long_poll_interval_received_;
- scoped_ptr<ModelSafeWorker> worker_;
+ scoped_refptr<ModelSafeWorker> worker_;
DISALLOW_COPY_AND_ASSIGN(SyncerTest);
};
diff --git a/chrome/browser/sync/glue/database_model_worker.cc b/chrome/browser/sync/glue/database_model_worker.cc
new file mode 100644
index 0000000..02516c7
--- /dev/null
+++ b/chrome/browser/sync/glue/database_model_worker.cc
@@ -0,0 +1,36 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/sync/glue/database_model_worker.h"
+
+#include "chrome/browser/chrome_thread.h"
+
+using base::WaitableEvent;
+
+namespace browser_sync {
+
+void DatabaseModelWorker::DoWorkAndWaitUntilDone(Closure* work) {
+ if (ChromeThread::CurrentlyOn(ChromeThread::DB)) {
+ DLOG(WARNING) << "DoWorkAndWaitUntilDone called from the DB thread.";
+ work->Run();
+ return;
+ }
+ WaitableEvent done(false, false);
+ if (!ChromeThread::PostTask(ChromeThread::DB, FROM_HERE,
+ NewRunnableMethod(this, &DatabaseModelWorker::CallDoWorkAndSignalTask,
+ work, &done))) {
+ NOTREACHED() << "Failed to post task to the db thread.";
+ return;
+ }
+ done.Wait();
+}
+
+void DatabaseModelWorker::CallDoWorkAndSignalTask(Closure* work,
+ WaitableEvent* done) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB));
+ work->Run();
+ done->Signal();
+}
+
+} // namespace browser_sync
diff --git a/chrome/browser/sync/glue/database_model_worker.h b/chrome/browser/sync/glue/database_model_worker.h
new file mode 100644
index 0000000..64f53ed
--- /dev/null
+++ b/chrome/browser/sync/glue/database_model_worker.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SYNC_GLUE_DATABASE_MODEL_WORKER_H_
+#define CHROME_BROWSER_SYNC_GLUE_DATABASE_MODEL_WORKER_H_
+
+#include "base/ref_counted.h"
+#include "base/waitable_event.h"
+#include "chrome/browser/sync/engine/model_safe_worker.h"
+#include "chrome/browser/sync/util/closure.h"
+
+namespace browser_sync {
+
+// A ModelSafeWorker for database models (eg. autofill) that accepts requests
+// from the syncapi that need to be fulfilled on the database thread.
+class DatabaseModelWorker : public browser_sync::ModelSafeWorker {
+ public:
+ explicit DatabaseModelWorker() {}
+
+ // ModelSafeWorker implementation. Called on syncapi SyncerThread.
+ void DoWorkAndWaitUntilDone(Closure* work);
+ virtual ModelSafeGroup GetModelSafeGroup() { return GROUP_DB; }
+
+ private:
+ void CallDoWorkAndSignalTask(Closure* work, base::WaitableEvent* done);
+
+ DISALLOW_COPY_AND_ASSIGN(DatabaseModelWorker);
+};
+
+} // namespace browser_sync
+
+#endif // CHROME_BROWSER_SYNC_GLUE_DATABASE_MODEL_WORKER_H_
diff --git a/chrome/browser/sync/glue/database_model_worker_unittest.cc b/chrome/browser/sync/glue/database_model_worker_unittest.cc
new file mode 100644
index 0000000..69ad5ce
--- /dev/null
+++ b/chrome/browser/sync/glue/database_model_worker_unittest.cc
@@ -0,0 +1,90 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/scoped_ptr.h"
+#include "base/thread.h"
+#include "base/timer.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/sync/glue/database_model_worker.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::OneShotTimer;
+using base::Thread;
+using base::TimeDelta;
+using browser_sync::DatabaseModelWorker;
+
+namespace {
+
+class DatabaseModelWorkerTest : public testing::Test {
+ public:
+ DatabaseModelWorkerTest() :
+ did_do_work_(false),
+ db_thread_(ChromeThread::DB),
+ io_thread_(ChromeThread::IO, &io_loop_),
+ ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {};
+
+ bool did_do_work() { return did_do_work_; }
+ DatabaseModelWorker* worker() { return worker_.get(); }
+ OneShotTimer<DatabaseModelWorkerTest>* timer() { return &timer_; }
+ ScopedRunnableMethodFactory<DatabaseModelWorkerTest>* factory() {
+ return &method_factory_;
+ }
+
+ // Schedule DoWork to be executed on the DB thread and have the test fail if
+ // DoWork hasn't executed within 10 seconds.
+ void ScheduleWork() {
+ scoped_ptr<Closure> c(NewCallback(this, &DatabaseModelWorkerTest::DoWork));
+ timer()->Start(TimeDelta::FromSeconds(10),
+ this, &DatabaseModelWorkerTest::Timeout);
+ worker()->DoWorkAndWaitUntilDone(c.get());
+ }
+
+ // This is the work that will be scheduled to be done on the DB thread.
+ void DoWork() {
+ EXPECT_TRUE(ChromeThread::CurrentlyOn(ChromeThread::DB));
+ timer_.Stop(); // Stop the failure timer so the test succeeds.
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE, new MessageLoop::QuitTask());
+ did_do_work_ = true;
+ }
+
+ // This will be called by the OneShotTimer and make the test fail unless
+ // DoWork is called first.
+ void Timeout() {
+ ADD_FAILURE() << "Timed out waiting for work to be done on the DB thread.";
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE, new MessageLoop::QuitTask());
+ }
+
+ protected:
+ virtual void SetUp() {
+ db_thread_.Start();
+ worker_ = new DatabaseModelWorker();
+ }
+
+ virtual void Teardown() {
+ worker_.release();
+ db_thread_.Stop();
+ }
+
+ private:
+ bool did_do_work_;
+ scoped_refptr<DatabaseModelWorker> worker_;
+ OneShotTimer<DatabaseModelWorkerTest> timer_;
+
+ ChromeThread db_thread_;
+ MessageLoopForIO io_loop_;
+ ChromeThread io_thread_;
+
+ ScopedRunnableMethodFactory<DatabaseModelWorkerTest> method_factory_;
+};
+
+TEST_F(DatabaseModelWorkerTest, DoesWorkOnDatabaseThread) {
+ MessageLoop::current()->PostTask(FROM_HERE, factory()->NewRunnableMethod(
+ &DatabaseModelWorkerTest::ScheduleWork));
+ MessageLoop::current()->Run();
+ EXPECT_TRUE(did_do_work());
+}
+
+} // namespace
diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc
index 4446659..269c9e4 100644
--- a/chrome/browser/sync/glue/sync_backend_host.cc
+++ b/chrome/browser/sync/glue/sync_backend_host.cc
@@ -33,9 +33,6 @@ SyncBackendHost::SyncBackendHost(SyncFrontend* frontend,
last_auth_error_(AuthError::None()) {
// Init our registrar state.
- for (int i = 0; i < MODEL_SAFE_GROUP_COUNT; i++)
- registrar_.workers[i] = NULL;
-
for (int i = 0; i < syncable::MODEL_TYPE_COUNT; i++) {
syncable::ModelType t(syncable::ModelTypeFromInt(i));
registrar_.routing_info[t] = GROUP_PASSIVE; // Init to syncing 0 types.
@@ -46,9 +43,7 @@ SyncBackendHost::SyncBackendHost(SyncFrontend* frontend,
SyncBackendHost::~SyncBackendHost() {
DCHECK(!core_ && !frontend_) << "Must call Shutdown before destructor.";
-
- for (int i = 0; i < MODEL_SAFE_GROUP_COUNT; ++i)
- DCHECK(registrar_.workers[i] == NULL);
+ DCHECK(registrar_.workers.empty());
}
void SyncBackendHost::Initialize(
@@ -115,8 +110,8 @@ void SyncBackendHost::Shutdown(bool sync_disabled) {
core_thread_.Stop();
registrar_.routing_info.clear();
- delete registrar_.workers[GROUP_UI];
registrar_.workers[GROUP_UI] = NULL;
+ registrar_.workers.erase(GROUP_UI);
frontend_ = NULL;
core_ = NULL; // Releases reference to core_.
}
@@ -160,10 +155,9 @@ const GoogleServiceAuthError& SyncBackendHost::GetAuthError() const {
void SyncBackendHost::GetWorkers(std::vector<ModelSafeWorker*>* out) {
AutoLock lock(registrar_lock_);
out->clear();
- for (int i = 0; i < MODEL_SAFE_GROUP_COUNT; i++) {
- if (registrar_.workers[i] == NULL)
- continue;
- out->push_back(registrar_.workers[i]);
+ for (WorkerMap::const_iterator it = registrar_.workers.begin();
+ it != registrar_.workers.end(); ++it) {
+ out->push_back((*it).second);
}
}
diff --git a/chrome/browser/sync/glue/sync_backend_host.h b/chrome/browser/sync/glue/sync_backend_host.h
index dd4db30..204dc6e 100644
--- a/chrome/browser/sync/glue/sync_backend_host.h
+++ b/chrome/browser/sync/glue/sync_backend_host.h
@@ -64,6 +64,8 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar {
typedef sync_api::UserShare* UserShareHandle;
typedef sync_api::SyncManager::Status::Summary StatusSummary;
typedef sync_api::SyncManager::Status Status;
+ typedef std::map<ModelSafeGroup,
+ scoped_refptr<browser_sync::ModelSafeWorker> > WorkerMap;
// Create a SyncBackendHost with a reference to the |frontend| that it serves
// and communicates to via the SyncFrontend interface (on the same thread
@@ -287,10 +289,9 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar {
// longer needed because all types that get routed to it have been disabled
// (from syncing). In that case, we'll destroy on demand *after* routing
// any dependent types to GROUP_PASSIVE, so that the syncapi doesn't call
- // into garbage. If an index is non-NULL, it means at least one ModelType
- // that routes to that model safe group is being synced.
- browser_sync::ModelSafeWorker*
- workers[browser_sync::MODEL_SAFE_GROUP_COUNT];
+ // into garbage. If a key is present, it means at least one ModelType that
+ // routes to that model safe group is being synced.
+ WorkerMap workers;
browser_sync::ModelSafeRoutingInfo routing_info;
} registrar_;
diff --git a/chrome/browser/sync/glue/ui_model_worker_unittest.cc b/chrome/browser/sync/glue/ui_model_worker_unittest.cc
index 85b02ab..e90033d 100644
--- a/chrome/browser/sync/glue/ui_model_worker_unittest.cc
+++ b/chrome/browser/sync/glue/ui_model_worker_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/ref_counted.h"
#include "base/thread.h"
#include "chrome/browser/sync/engine/syncapi.h"
#include "chrome/browser/sync/glue/ui_model_worker.h"
@@ -47,7 +48,7 @@ class Syncer {
worker_->DoWorkAndWaitUntilDone(c.get());
}
private:
- UIModelWorker* worker_;
+ scoped_refptr<UIModelWorker> worker_;
DISALLOW_COPY_AND_ASSIGN(Syncer);
};
@@ -92,7 +93,7 @@ class FakeSyncapiShutdownTask : public Task {
}
private:
base::Thread* syncer_thread_;
- UIModelWorker* worker_;
+ scoped_refptr<UIModelWorker> worker_;
base::WaitableEvent** jobs_;
size_t job_count_;
base::WaitableEvent all_jobs_done_;
@@ -106,7 +107,7 @@ class UIModelWorkerTest : public testing::Test {
virtual void SetUp() {
faux_syncer_thread_.Start();
- bmw_.reset(new UIModelWorker(&faux_ui_loop_));
+ bmw_ = new UIModelWorker(&faux_ui_loop_);
syncer_.reset(new Syncer(bmw_.get()));
}
@@ -119,7 +120,7 @@ class UIModelWorkerTest : public testing::Test {
MessageLoop faux_ui_loop_;
base::Thread faux_syncer_thread_;
base::Thread faux_core_thread_;
- scoped_ptr<UIModelWorker> bmw_;
+ scoped_refptr<UIModelWorker> bmw_;
scoped_ptr<Syncer> syncer_;
};
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 33976a9..0c0a453 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1594,6 +1594,8 @@
'browser/sync/glue/bookmark_model_associator.cc',
'browser/sync/glue/change_processor.cc',
'browser/sync/glue/change_processor.h',
+ 'browser/sync/glue/database_model_worker.cc',
+ 'browser/sync/glue/database_model_worker.h',
'browser/sync/glue/http_bridge.cc',
'browser/sync/glue/http_bridge.h',
'browser/sync/glue/model_associator.h',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index a74e318..e77daa5 100755
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -797,6 +797,7 @@
'browser/shell_integration_unittest.cc',
'browser/spellchecker_platform_engine_unittest.cc',
'browser/ssl/ssl_host_state_unittest.cc',
+ 'browser/sync/glue/database_model_worker_unittest.cc',
'browser/sync/glue/http_bridge_unittest.cc',
'browser/sync/glue/ui_model_worker_unittest.cc',
'browser/sync/profile_sync_service_unittest.cc',