Chromium Code Reviews| Index: components/profile_service/profile_app.cc |
| diff --git a/components/profile_service/profile_app.cc b/components/profile_service/profile_app.cc |
| index 27491db5e910d27946721e9031860a493591c71b..d3cc4eb200570f7a387ec1d26ac8812ba9ef66b3 100644 |
| --- a/components/profile_service/profile_app.cc |
| +++ b/components/profile_service/profile_app.cc |
| @@ -4,46 +4,95 @@ |
| #include "components/profile_service/profile_app.h" |
| -#include "base/lazy_instance.h" |
| +#include "base/bind.h" |
| +#include "base/memory/weak_ptr.h" |
| +#include "components/filesystem/lock_table.h" |
| #include "components/leveldb/leveldb_service_impl.h" |
| #include "components/profile_service/profile_service_impl.h" |
| +#include "components/profile_service/user_id_map.h" |
| +#include "mojo/public/cpp/bindings/callback.h" |
| #include "mojo/shell/public/cpp/connection.h" |
| namespace profile { |
| -namespace { |
| - |
| -base::LazyInstance<std::map<std::string, base::FilePath>> |
| - g_user_id_to_data_dir = LAZY_INSTANCE_INITIALIZER; |
| - |
| -} // namespace |
| - |
| -scoped_ptr<mojo::ShellClient> CreateProfileApp() { |
| - return make_scoped_ptr(new ProfileApp); |
| +class ProfileApp::ProfileServiceObjects |
| + : public base::SupportsWeakPtr<ProfileServiceObjects> { |
| + public: |
| + // Created on the main thread. |
| + ProfileServiceObjects(base::FilePath profile_data_dir) |
| + : profile_data_dir_(profile_data_dir) {} |
| + |
| + // Destroyed on the |profile_service_runner_|. |
| + ~ProfileServiceObjects() {} |
| + |
| + // Called on the |profile_service_runner_|. |
| + void OnProfileServiceRequest(mojo::Connection* connection, |
| + ProfileServiceRequest request) { |
| + if (!lock_table_) |
| + lock_table_ = new filesystem::LockTable; |
| + profile_service_bindings_.AddBinding( |
| + new ProfileServiceImpl(profile_data_dir_, lock_table_), |
| + std::move(request)); |
| + } |
| + |
| + private: |
| + mojo::BindingSet<ProfileService> profile_service_bindings_; |
| + scoped_refptr<filesystem::LockTable> lock_table_; |
| + base::FilePath profile_data_dir_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ProfileServiceObjects); |
| +}; |
| + |
| +class ProfileApp::LevelDBServiceObjects |
|
michaeln
2016/03/17 22:35:41
nice arrangement for thread safety!
|
| + : public base::SupportsWeakPtr<LevelDBServiceObjects> { |
| + public: |
| + // Created on the main thread. |
| + LevelDBServiceObjects() {} |
| + |
| + // Destroyed on the |leveldb_service_runner_|. |
| + ~LevelDBServiceObjects() {} |
| + |
| + // Called on the |leveldb_service_runner_|. |
| + void OnLevelDBServiceRequest(mojo::Connection* connection, |
| + leveldb::LevelDBServiceRequest request) { |
| + if (!leveldb_service_) |
| + leveldb_service_.reset(new leveldb::LevelDBServiceImpl); |
|
michaeln
2016/03/17 22:35:41
does this direct instantiation mean we're not usin
Elliot Glaysher
2016/03/18 19:41:12
Correct. Apps don't contain other apps. Apps conta
|
| + leveldb_bindings_.AddBinding(leveldb_service_.get(), std::move(request)); |
| + } |
| + |
| + private: |
| + // Variables that are only accessible on the |leveldb_service_runner_| thread. |
| + scoped_ptr<leveldb::LevelDBService> leveldb_service_; |
| + mojo::BindingSet<leveldb::LevelDBService> leveldb_bindings_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(LevelDBServiceObjects); |
| +}; |
| + |
| +scoped_ptr<mojo::ShellClient> CreateProfileApp( |
| + const scoped_refptr<base::SingleThreadTaskRunner>& profile_service_runner, |
| + const scoped_refptr<base::SingleThreadTaskRunner>& leveldb_service_runner) { |
| + return make_scoped_ptr( |
| + new ProfileApp(profile_service_runner, leveldb_service_runner)); |
| } |
| -ProfileApp::ProfileApp() |
| - : lock_table_(new filesystem::LockTable) { |
| -} |
| - |
| -ProfileApp::~ProfileApp() {} |
| +ProfileApp::ProfileApp( |
| + const scoped_refptr<base::SingleThreadTaskRunner>& profile_service_runner, |
| + const scoped_refptr<base::SingleThreadTaskRunner>& leveldb_service_runner) |
| + : profile_service_runner_(profile_service_runner), |
| + leveldb_service_runner_(leveldb_service_runner) {} |
| -// static |
| -void ProfileApp::AssociateMojoUserIDWithProfileDir( |
| - const std::string& user_id, |
| - const base::FilePath& profile_data_dir) { |
| - g_user_id_to_data_dir.Get()[user_id] = profile_data_dir; |
| +ProfileApp::~ProfileApp() { |
| + profile_service_runner_->DeleteSoon(FROM_HERE, profile_objects_.release()); |
| + leveldb_service_runner_->DeleteSoon(FROM_HERE, leveldb_objects_.release()); |
| } |
| void ProfileApp::Initialize(mojo::Connector* connector, |
| const mojo::Identity& identity, |
| uint32_t id) { |
| tracing_.Initialize(connector, identity.name()); |
| - leveldb_service_.reset(new leveldb::LevelDBServiceImpl); |
| - |
| - auto it = g_user_id_to_data_dir.Get().find(identity.user_id()); |
| - DCHECK(it != g_user_id_to_data_dir.Get().end()); |
| - profile_data_dir_ = it->second; |
| + profile_objects_.reset(new ProfileApp::ProfileServiceObjects( |
| + GetProfileDirForUserID(identity.user_id()))); |
| + leveldb_objects_.reset(new ProfileApp::LevelDBServiceObjects); |
| } |
| bool ProfileApp::AcceptConnection(mojo::Connection* connection) { |
| @@ -54,16 +103,20 @@ bool ProfileApp::AcceptConnection(mojo::Connection* connection) { |
| void ProfileApp::Create(mojo::Connection* connection, |
| ProfileServiceRequest request) { |
| - // No, we need one of these per connection. |
| - new ProfileServiceImpl(connection, |
| - std::move(request), |
| - profile_data_dir_, |
| - lock_table_.get()); |
| + profile_service_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&ProfileApp::ProfileServiceObjects::OnProfileServiceRequest, |
| + profile_objects_->AsWeakPtr(), connection, |
| + base::Passed(&request))); |
| } |
| void ProfileApp::Create(mojo::Connection* connection, |
| leveldb::LevelDBServiceRequest request) { |
| - leveldb_bindings_.AddBinding(leveldb_service_.get(), std::move(request)); |
| + leveldb_service_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&ProfileApp::LevelDBServiceObjects::OnLevelDBServiceRequest, |
| + leveldb_objects_->AsWeakPtr(), connection, |
| + base::Passed(&request))); |
| } |
| } // namespace profile |